首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

共享模式与基于 Condition 的等待 / 通知机制实现(7)

共享模式与基于 Condition 的等待 / 通知机制实现(7)

这个类里面的方法就不解释了,反正就三个方法片段,根据线程名判断,每个线层执行的是其中的一个代码片段。写一段测试代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* @author 五月的仓颉http://www.cnblogs.com/xrq730/p/7067904.html
*/
@Test
public void testCondition() throws Exception {
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();
         
    // 线程0的作用是signal
    Runnable runnable0 = new ConditionThread(lock, condition);
    Thread thread0 = new Thread(runnable0);
    thread0.setName("线程0");
    // 线程1的作用是await
    Runnable runnable1 = new ConditionThread(lock, condition);
    Thread thread1 = new Thread(runnable1);
    thread1.setName("线程1");
    // 线程2的作用是lock
    Runnable runnable2 = new ConditionThread(lock, condition);
    Thread thread2 = new Thread(runnable2);
    thread2.setName("线程2");
         
    thread1.start();
    Thread.sleep(1000);
    thread0.start();
    Thread.sleep(1000);
    thread2.start();
         
    thread1.join();
}



测试代码的意思是:
  • 线程1先启动,获取锁,调用await()方法等待
  • 线程0后启动,获取锁,休眠5秒准备signal()
  • 线程2最后启动,获取锁,由于线程0未使用完毕锁,因此线程2排队,可以此时由于线程0还未signal(),因此线程1在线程0执行signal()后,在AbstractQueuedSynchronizer队列中的顺序是在线程2后面的
代码执行结果为:
1
2
3
4
5
6
1 线程1阻塞
2 线程0休息5秒
3 线程2想要获取锁
4 线程0唤醒等待线程
5 线程2获取锁成功
6 线程1被唤醒



符合我们的结论:signal()并不意味着被唤醒的线程立即执行。由于线程2先于线程0排队,因此看到第5行打印的内容,线程2先获取锁。
返回列表