您的位置:首页 > 其它

学习日记1105--多线程间的通信(生产者消费者)(1)

2014-11-05 20:23 162 查看
<p>今天主要学习了多线程间的通信,并对毕老师所讲的内容作了认真的理解分析,内容整理如下: </p><p>在生产者消费者程序运行过程中,可能出现生产两个消费一个或者生产一个消费两个的情况,如下图所示。对其产生原因进行分析,并指出改进方法。</p><p><img src="http://img.blog.csdn.net/20141105202626609?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDM3ODMyMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" /></p><p><span style="font-family: Arial, Helvetica, sans-serif;">生产者消费者两个进程中的同步代码如下:</span></p><p><span style="font-family: Arial, Helvetica, sans-serif;"></span><pre name="code" class="java">public synchronized void input(String name)
{
if(flag)
try
{
this.wait();
}
catch (Exception e)
{
}
this.name = name + count++;
System.out.println(Thread.currentThread().getName()+"...生产者"+this.name);
flag = true;
this.notify();
}

public synchronized void out()
{
if(!flag)
try
{
this.wait();
}
catch (Exception e)
{
}
System.out.println(Thread.currentThread().getName()+"-----------消费者"+this.name);
flag = false;
notify();
}


对其执行过程进行分析:



根本原因:唤醒本方线程,且t1唤醒t2时,直接从等待位置,直接向下执行而未判断标记。

解决办法:(1)循环判断标记,将if条件判断,改为while循环判断

(2)唤醒对方线程,将notify()(仅唤醒线程池中的一个线程)改为notifyAll()(唤醒线程池中的所有线程)

改进后的代码如下:
public synchronized void input(String name)
{
while(flag)
try
{
this.wait();
}
catch (Exception e)
{
}
this.name = name + count++;
System.out.println(Thread.currentThread().getName()+"...生产者"+this.name);
flag = true;
this.notifyAll();
}

public synchronized void out()
{
while(!flag)
try
{
this.wait();
}
catch (Exception e)
{
}
System.out.println(Thread.currentThread().getName()+"-----------消费者"+this.name);
flag = false;
notifyAll();
}


接下来是JDK1.5中对多线程的升级方案


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: