黑马程序员技术交流社区
标题: 多线程的同步、通讯2 [打印本页]
作者: jk7130866 时间: 2015-7-25 11:20
标题: 多线程的同步、通讯2
继续刚才的话题看到了吧做了好几此饭才吃了一次,这不合理吧,我们怎么让做一次饭吃一次饭,通讯的机制是锁对象的wait(),notify()机制l来实现一下吧,class Fan{
private Fan() {
// TODO Auto-generated constructor stub
}
private static Fan fan=new Fan();//单例化 两个人做的做的同一件事
public static Fan getingstane(){
return fan;
}
private String attr="生的";//饭的属性方便演示
public void cook(){
synchronized (fan) {
if("熟了".equals(attr))
{
try {
fan.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
taomi();
zhengmi();
fan.notify();
}
}
private void taomi(){
attr="生的";
System.out.println("淘米"+"........"+attr);
}
private void zhengmi(){
attr="生的";
System.out.println("蒸米"+"........"+attr);
try {
Thread.currentThread().sleep(10);//模拟蒸饭的时间
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
attr="熟了";
System.out.println("做好了"+"........"+attr);
}
public void eat(){
synchronized (fan) {
if("生的".equals(attr)){
try {
fan.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
chengfan();
chifan();
fan.notify();
}
}
private void chengfan(){
System.out.println(attr+"....."+"盛好了");
}
private void chifan(){
System.out.println(attr+"....."+"吃完了");
attr="生的";//吃完了饭的属性又回到生的
}
}
红色的字体是修改的代码,简单实现了等待唤醒机制看看结果
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了
淘米........生的
蒸米........生的
做好了........熟了
熟了.....盛好了
熟了.....吃完了看到了把做一次饭吃次饭,它的实现机制是什么,原理很简单,线程当一个线程持有一个锁对象,当锁对象吊用自己的wait()方法该线程冻结,比释放锁,让别的线程可以进来。所以这种方式只能用在同步当中哦!!掉用notify()方法可以唤醒线程池当中的了、第一个线程,这里只有两个线程,所以唤醒的一定是对方线程,保证下次一定会有两个识别不同表示的线程进入同步,以防全部冻结,程序进行执行不了。如果不知两个线程执行呢,我把线程这样分类,同样功能的线程成为本方线程,对应的执行另一个功能线程叫做对方线程。现在再两个线程看看把
new Thread(zuofan,"做饭线程1").start();
new Thread(zuofan,"做饭线程2").start();
new Thread(chifan,"吃饭线程1").start();
new Thread(chifan,"吃饭线程2").start();
加上线程的名字看的更清楚,看看结果
熟了.....盛好了吃饭线程2
熟了.....吃完了吃饭线程2
生的.....盛好了吃饭线程1
生的.....吃完了吃饭线程1
淘米........生的做饭线程2
蒸米........生的做饭线程2
做好了........熟了做饭线程2
熟了.....盛好了吃饭线程2
熟了.....吃完了吃饭线程2现在先来看看那刚才出现的情况吧这是怎么回事呢做么有乱了,分析一下,饭线程1准备吃饭发现饭是生的
if("生的".equals(attr)){
try {
fan.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
chengfan();
chifan();
fan.notify();
}
}
挂在了这,做饭线程进来做好饭,接着吃饭吃饭线程2来了他吃完了,唤醒等待整的线程,这里是饭线程1他醒了取得锁,从挂起来的地方开始执行,还进行判断吗,if语句是执行完语句体就继续只、执行下面的语句也就是chengfan();问题来了吧,这时候饭是生的的,没进行判断继续了,只要让他醒来就先判断自己该不该继续等带就行了,用whlie语句修改看看结果
蒸米........生的做饭线程1
做好了........熟了做饭线程1
熟了.....盛好了吃饭线程2
熟了.....吃完了吃饭线程2
淘米........生的做饭线程2
蒸米........生的做饭线程2
做好了........熟了做饭线程2
不乱了,但是怎么卡住了是这样的当对方线程都进入冻结,本方线程执行完,唤醒的还是本方线程那就挂了,怎么才能保证对方线程一定被唤醒呢,简单noyifyall();就Ok了;试试把,结果可行我就补贴出来了。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |