黑马程序员技术交流社区
标题:
线程问题
[打印本页]
作者:
treecolor166
时间:
2013-12-28 13:48
标题:
线程问题
本帖最后由 treecolor166 于 2013-12-29 23:55 编辑
请问下面的代码为什么只有2个线程在打印其它线程怎么都停在那里不输出了呢
public class ProducerConsumerDemo2
{
public static void main(String[] args)
{
Resource r=new Resource();
Producer pro=new Producer(r);
Consumer con=new Consumer(r);
Thread t1=new Thread(pro);
Thread t2=new Thread(pro);
Thread t3=new Thread(con);
Thread t4=new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resource
{
private String name;
private int count=1;
private boolean flag;
//创建锁
Lock lock=new ReentrantLock();
//通过锁对象创建2组监视器对象,分别用于监视生产者和消费者
Condition producer_con=lock.newCondition();
Condition consumer_con=lock.newCondition();
public synchronized void set(String name)
{
lock.lock();
try
{
while(flag)
try{producer_con.await();}catch(InterruptedException e){}
this.name=name+(count++);
System.out.println(Thread.currentThread().getName()+"....生产"+this.name);
flag=true;
consumer_con.signal();
}
finally
{
lock.unlock();
}
}
public synchronized void out()
{
lock.lock();
try
{
while(!flag)
try{consumer_con.await();}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"*************消费"+this.name);
flag=false;
producer_con.signal();
}
finally
{
lock.unlock();
}
}
}
class Producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.set("商品");
}
}
}
class Consumer implements Runnable
{
private Resource r;
Consumer(Resource r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
作者:
胡永城
时间:
2013-12-28 20:00
本帖最后由 胡永城 于 2013-12-28 20:01 编辑
真心纠结的问题啊,不过找到问题了:
Resource类中,public synchronized void set(String name) 方法中:
producer_con.await();//这一句。
当线程Thread-0执行到这一句时,此线程拿着此方法的锁this,处于等待状态。
(API文档:
void
await
()
throws
InterruptedException
造成当前线程在接到信号或被
中断
之前一直处于等待状态。)
此时如果Thread-1执行到public synchronized void set(String name) 方法。
this锁被Thread-0拿着,没有线程执行consumer_con.signal();语句。Thread-0冻结状态,Thread-1进不来方法。。。
同样的Thread-2、Thread-3也发生这种情况,造成死锁,所以程序就卡在这里了。
以下是测试代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//请问下面的代码为什么只有2个线程在打印其它线程怎么都停在那里不输出了呢
public class ProducerConsumerDemo2 {
public static void main(String[] args) {
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
//只测试t1、t2构成的死锁。也可以同时测t3、t4.
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
//Thread t3 = new Thread(con);
//Thread t4 = new Thread(con);
t1.start();
t2.start();
//t3.start();
// t4.start();
}
}
class Resource {
static int p=0;//此静态变量用于监视执行顺序。
private String name;
private int count = 1;
private boolean flag;
// 创建锁
Lock lock = new ReentrantLock();
// 通过锁对象创建2组监视器对象,分别用于监视生产者和消费者
Condition producer_con = lock.newCondition();
Condition consumer_con = lock.newCondition();
public synchronized void set(String name) {
lock.lock();
System.out.println(Thread.currentThread().getName() +"---set-上--"+Resource.p+++"---"+flag);//监视
try {
while (flag)
try {
System.out.println(Thread.currentThread().getName() +"---set---"+Resource.p+++"---"+flag);//监视
producer_con.await();
System.out.println(Thread.currentThread().getName() +"---set-await--"+Resource.p+++"---"+flag);//监视
} catch (InterruptedException e) {
}
this.name = name + (count++);
System.out.println(Thread.currentThread().getName() + "....生产"
+ this.name);
flag = true;
System.out.println(Thread.currentThread().getName() +"---set-下--"+Resource.p+++"---"+flag);//监视
consumer_con.signal();
} finally {
lock.unlock();
}
}
public synchronized void out() {
//System.out.println(Thread.currentThread().getName() +"---out()-上--"+Resource.p+++"---"+flag);
lock.lock();
try {
while (!flag)
try {
consumer_con.await();
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName()
+ "*************消费" + this.name);
flag = false;
//System.out.println(Thread.currentThread().getName() +"---out()-下--"+Resource.p+++"---"+flag);
producer_con.signal();
} finally {
lock.unlock();
}
}
}
class Producer implements Runnable {
private Resource r;
Producer(Resource r) {
this.r = r;
}
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName() +"--Producer-run()---"+Resource.p+++"---");//监视
r.set("商品");
}
}
}
class Consumer implements Runnable {
private Resource r;
Consumer(Resource r) {
this.r = r;
}
public void run() {
while (true) {
//System.out.println(Thread.currentThread().getName() +"--Consumer-run()---"+Resource.p+++"---");
r.out();
}
}
}
复制代码
我只发现了这个情况,如果有其他的情况和我说说啊。
作者:
treecolor166
时间:
2013-12-29 00:35
多谢你的提醒,把synchronized去掉之后就正常了
作者:
胡永城
时间:
2013-12-29 03:04
treecolor166 发表于 2013-12-29 00:35
多谢你的提醒,把synchronized去掉之后就正常了
我第一次回答有一点错误:
“
producer_con.await();//这一句。
当线程Thread-0执行到这一句时,此线程拿着此方法的锁this,处于等待状态。
”
这两句,我当时理解为没有释放锁,其实释放锁了。希望对你不要产生错误的引导。
await方法:与此 Condition 相关的锁以原子方式释放,并且出于线程调度的目的,将禁用当前线程。
同步方法的锁是this,就是此方法的调用者。执行await后, Condition 相关的锁被释放,this锁却没有释放。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2