博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面试题 - 使用线程交替打印奇数偶数
阅读量:6573 次
发布时间:2019-06-24

本文共 4233 字,大约阅读时间需要 14 分钟。

这世上有三样东西是别人抢不走的:一是吃进胃里的食物,二是藏在心中的梦想,三是读进大脑的书

  • 分析题目。需要使用两个线程交替打印奇偶数。
    • 使用同步锁解决这个问题
    • 使用信号量来实现交替打印
  • 定义两个信号量,一个奇数信号量,一个偶数信号量,都初始化为1
  • 先用掉偶数的信号量,因为要让奇数先启动,等奇数打印完再释放

信号量实现

  • 具体实现思路:
    • 定义两个信号量,一个奇数信号量,一个偶数信号量,都初始化为1
    • 先用掉偶数的信号量,因为要让奇数先启动,等奇数打印完再释放
    • 具体流程就是 第一次的时候先减掉偶数的信号量 奇数线程打印完成以后用掉奇数的信号量。然后释放偶数的信号量如此循环
import java.util.concurrent.Semaphore;/** * @ClassName AlternatePrinting * @Author yunlogn * @Date 2019/5/21  * @Description 交替打印奇偶数 */public class AlternatePrinting {	static int i = 0;	public static void main(String[] args) throws InterruptedException {      Semaphore semaphoreOdd = new Semaphore(1);		 Semaphore semaphoreEven = new Semaphore(1);      semaphoreOdd.acquire();  //让奇数先等待启动,所以先减掉偶数的信号量 等奇数线程来释放		SemaphorePrintEven semaphorePrintEven = new SemaphorePrintEven(semaphoreOdd, semaphoreEven);		Thread t1 = new Thread(semaphorePrintEven);		t1.start();		SemaphorePrintOdd semaphorePrintOdd = new SemaphorePrintOdd(semaphoreOdd, semaphoreEven);		Thread t2 = new Thread(semaphorePrintOdd);		t2.start();	}	/**	 * 使用信号量实现	 */	static class SemaphorePrintOdd implements Runnable {		private Semaphore semaphoreOdd;		private Semaphore semaphoreEven;		public SemaphorePrintOdd(Semaphore semaphoreOdd, Semaphore semaphoreEven) {			this.semaphoreOdd = semaphoreOdd;			this.semaphoreEven = semaphoreEven;		}		@Override		public void run() {			try {            				semaphoreOdd.acquire();//获取信号量 semaphoreOdd在初始化的时候被获取了信号量所以这里被阻塞了,所以会先执行下面的奇数线程				while (true) {					i++;					if (i % 2 == 0) {						System.out.println("偶数线程:" + i);						semaphoreEven.release();//释放偶数信号量 让奇数线程那边的阻塞解除						//再次申请获取偶数信号量,因为之前已经获取过,如果没有奇数线程去释放,那么就会一直阻塞在这,等待奇数线程释放						semaphoreOdd.acquire();					}				}			} catch (InterruptedException e) {				e.printStackTrace();			}		}	}	static class SemaphorePrintEven implements Runnable {		private Semaphore semaphoreOdd;		private Semaphore semaphoreEven;		public SemaphorePrintEven(Semaphore semaphoreOdd, Semaphore semaphoreEven) {			this.semaphoreOdd = semaphoreOdd;			this.semaphoreEven = semaphoreEven;		}		@Override		public void run() {			try {                     				semaphoreEven.acquire(); 				while (true) {					i++;					if (i % 2 == 1) {						System.out.println("奇数线程:" + i);						semaphoreOdd.release(); //释放奇数信号量 让偶数线程那边的阻塞解除						                //这里阻塞,等待偶数线程释放信号量                //再次申请获取奇数信号量,需要等偶数线程执行完然后释放该信号量,不然阻塞                semaphoreEven.acquire();					}				}			} catch (Exception ex) {}		}	}}复制代码
  • 需要注意的是,如果某个线程来不及释放就异常中断了,会导致另一个线程一直在等,造成死锁。 虽然这个异常不在这个问题的考虑范围内 但是可以使用finally 来包裹释放锁资源

同步锁打印

  • 让两个线程使用同一把锁。交替执行 。
    • 判断是不是奇数 如果是奇数进入奇数线程执行打印并加一。然后线程释放锁资源。然后让该线程等待
    • 判断是不是偶数,如果是偶数进入偶数线程执行打印并加一。然后线程释放锁资源。然后让该线程等待
import java.util.concurrent.atomic.AtomicInteger;/** * @ClassName AlternatePrinting * @Author yunlogn * @Date 2019/5/21 * @Description 交替打印奇偶数 */public class AlternatePrinting {	public static AtomicInteger atomicInteger = new AtomicInteger(1);	public static void main(String[] args) throws InterruptedException {		Thread a=new Thread(new AThread());		Thread b=new Thread(new BThread());		a.start();		b.start();	}	public static class AThread implements Runnable {		@Override		public void run() {			while (true) {				synchronized (atomicInteger) {					if (atomicInteger.intValue() % 2 != 0) {						System.out.println("奇数线程:" + atomicInteger.intValue());						atomicInteger.getAndIncrement();						// 奇数线程释放锁资源						atomicInteger.notify();						try {							atomicInteger.wait();						} catch (InterruptedException e) {							e.printStackTrace();						}					} else {						try {							// 奇数线程等待							atomicInteger.wait();						} catch (InterruptedException e) {							e.printStackTrace();						}					}				}			}		}	}	public static class BThread implements Runnable {		@Override		public void run() {			while (true){				synchronized (atomicInteger){					if(atomicInteger.intValue() %2== 0 ){						System.out.println("偶数线程:"+ atomicInteger.intValue());						atomicInteger.getAndIncrement();						// 偶数线程释放锁资源						atomicInteger.notify();						try {							atomicInteger.wait();						} catch (InterruptedException e) {							e.printStackTrace();						}					}else{						try {							// 偶数线程等待							atomicInteger.wait();						} catch (InterruptedException e) {							e.printStackTrace();						}					}				}			}		}	}}复制代码

转载地址:http://ermjo.baihongyu.com/

你可能感兴趣的文章
加密算法使用(五):RSA使用全过程
查看>>
root用户重置其他密码
查看>>
C#------如何获取本机IP地址
查看>>
关于查询扩展版ESI高被引论文的说明
查看>>
【iCore3应用】基于iCore3双核心板的编码器应用实例
查看>>
Oracle推断值为非数字
查看>>
得知发行组长老潘今天岗位上最后一天就要离开有感
查看>>
[转]WF事件驱动(1)
查看>>
异常关闭MyEclipse 8.6后,不能重启
查看>>
android recover 系统代码分析 -- 选择进入
查看>>
问卷调查模块实现的过程中的历程
查看>>
排序合并连接(sort merge join)的原理
查看>>
【转】CCScale9Sprite和CCControlButton
查看>>
多年前写的一个ASP.NET网站管理系统,到现在有些公司在用
查看>>
解决Web部署 svg/woff/woff2字体 404错误
查看>>
经验总结21--抓取WEB数据,汇率,HtmlAgilityPack
查看>>
TThread类详解<转>
查看>>
查看数据库文件大小写
查看>>
26个充满创意的平面广告作品欣赏
查看>>
格式当前时间mongodb date type
查看>>