A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© daoqin 高级黑马   /  2014-9-12 21:45  /  944 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 daoqin 于 2014-9-12 21:47 编辑

Java多线程的等待/唤醒机制:
用到的方法:
1.wait()  让线程处于冻结状态,被wait线程会被存储在线程等待池中
2.notify()  唤醒线程等待池中的一个线程(任意)
3.notifyAll()  唤醒线程等待池中的全部线程
这些方法由于是监视器(其实就是线程同步锁)的方法,因此操作线程的方法wait()、notify()、notifyAll()必须定义在Object类中。

sleep() 方法和wait() 的区别:
1、这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。
sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用了b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。
2、最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。
Thread.Sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。
3、使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用     
   synchronized(x){     
      x.notify()     
     //或者wait()     
   }
4、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

JDK1.5以后,对于线程安全问题有了新的处理方式——接口 Lock
Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的
Condition对象。
ConditionObject 监视器方法(waitnotifynotifyAll)分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用,为每个对象提供多个等待
set(wait-set)。其中,Lock 替代了synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。  
Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,可以使用Lock.newConditon() 方法。

生产者与消费者问题:
作为一个示例,假定有一个绑定的缓冲区,它支持 put 和 take 方法。如果试图在空的缓冲区上执行 take 操作,则在某一个项变得可用之前,线程将一直阻塞;如果试图在满的缓冲区上执行 put 操作,则在有空间变得可用之前,线程将一直阻塞。我们喜欢在单独的等待 set 中保存 put 线程和 take 线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程。可以使用两个 Condition 实例来做到这一点。
下面的代码是JDK中文参考给出的示例代码,很实用!
  1. class BoundedBuffer {
  2.    final Lock lock = new ReentrantLock();
  3.    final Condition notFull  = lock.newCondition();
  4.    final Condition notEmpty = lock.newCondition();

  5.    final Object[] items = new Object[100];
  6.    int putptr, takeptr, count;

  7.    public void put(Object x) throws InterruptedException {
  8.      lock.lock();
  9.      try {
  10.        while (count == items.length)
  11.          notFull.await();
  12.        items[putptr] = x;
  13.        if (++putptr == items.length) putptr = 0;
  14.        ++count;
  15.        notEmpty.signal();
  16.      } finally {
  17.        lock.unlock();
  18.      }
  19.    }

  20.    public Object take() throws InterruptedException {
  21.      lock.lock();
  22.      try {
  23.        while (count == 0)
  24.          notEmpty.await();
  25.        Object x = items[takeptr];
  26.        if (++takeptr == items.length) takeptr = 0;
  27.        --count;
  28.        notFull.signal();
  29.        return x;
  30.      } finally {
  31.        lock.unlock();
  32.      }
  33.    }
  34. }
复制代码






评分

参与人数 1技术分 +1 收起 理由
舍我其谁 + 1

查看全部评分

您需要登录后才可以回帖 登录 | 加入黑马