黑马程序员技术交流社区

标题: 关于多线程同步问题 [打印本页]

作者: 肖琦    时间: 2012-7-25 13:43
标题: 关于多线程同步问题
本帖最后由 肖琦 于 2012-7-28 09:19 编辑

当一个线程T1获得一个Lock L 后,此时的某些变量还没有达到T1所希望的条件,所以T1在 L 的某个Condition C上await,这里的await相当于释放了 L 并使T1进入休眠状态吗?
如果 L 已经被T1 n次进入,await是否相当于调用了n次L的unlock方法,并进入休眠状态。
现在,其它的某个线程T2进入了锁 L ,执行一些操作后,调用C的signalAll方法,此时T1的状态具体会发生什么样的变化?
请教各位高手,能从操作系统的层面上解释上述过程中线程状态的一些变化吗?
比如:T2调用了C的signalAll方法,而此时T2还没有释放L,因为调用unlock是在signalAll之后的,那么现在T1是不是从休眠状态进入阻塞状态?这两种状态的区别是什么?
另外,如果T1出了await方法后,是否会重新n次进入L?求详解,越底层越好。

作者: 刘海源    时间: 2012-7-25 19:44
class Resource
{
private String name;
private int count = 1;
private boolean flag;
//创建一个锁对象。
private final Lock lock = new ReentrantLock();
//获取一个该锁上的监视器。
private Condition con = lock.newCondition();

public  void set(String name)//  
{
  //获取锁。
  lock.lock();
  try
  {
  
   while(flag)
    try{con.await();}catch(InterruptedException e){}//t0(活-->wait) t1(活)
   this.name = name + count;//馒头1 馒头2 馒头3
   count++;
   System.out.println(Thread.currentThread().getName()+".....生产者......"+this.name);//Thread-0 生产 馒头1
                       //Thread-0 生产 馒头2
                       //Thread-0 生产 馒头3
   flag = true;
   con.signalAll();//唤醒了消费者的其中一个线程
  }
  finally
  {
   //释放锁。
   lock.unlock();
  }
}
public  void get()//  
{
  lock.lock();
  try
  {
   
  
   while(!flag)
    try{con.await();}catch(InterruptedException e){}//t2  t3
   System.out.println(Thread.currentThread().getName()+".........消费者......"+this.name);//Thread-2 消费 馒头1
   flag = false;
   con.signalAll();
  }
  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.get();
  }
}
}

class  ProConDemo3
{
public static void main(String[] args)
{
  Resource r = new Resource();
  Producer pro = new Producer(r);
  Consumer con = new Consumer(r);
  //两个线程负责生产。
  Thread t0 = new Thread(pro);
  Thread t1 = new Thread(pro);
  //两个线程负责消费。
  Thread t2 = new Thread(con);
  Thread t3 = new Thread(con);
  t0.start();
  t1.start();
  t2.start();
  t3.start();
}
}
休眠状态具有执行资格和执行权,而阻塞状态只有执行资格没有执行权了
下面给你给图看看:

P}G}X2M%ZWNZ_OPXMHZ_L9X.jpg (29.36 KB, 下载次数: 23)

P}G}X2M%ZWNZ_OPXMHZ_L9X.jpg





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2