以生产者消费者的那个例子解释的话就是, 使用synchronized的话, 你把生产者线程等待后你想要唤醒消费者其他线程, 这时候你只能唤醒其他所有的线程才可以, 万一你唤醒的还是生产者线程呢? 程序就会挂掉的哦
其实吧, Lock替代了synchronized方法和语句, 同时功能更加强大, 不然Lock的出现没有任何意义, Condition替代了Object监视器的方法, 同时功能更加强大, 好处就是释放线程的时候可以选择只释放对方线程, 这样写起来绝对会很爽的哦
为什么呢? 还是生产者消费者的那个例子, 使用 synchronized 的话, 如果想唤醒对方线程, 只有一种方法, 使用notifyAll() 唤醒其他所有线程,否则可能全部等待, 而使用 Lock + Condition的话, 你就可以选择只释放对方线程的
使用 synchronized 的代码
- class Goods {
- private String name; private int count = 1;
- private boolean flag = false;
- public synchronized void set(String name) {
-
- while (flag)// 如果用if()循环,操作set的进程就只能有一个
- try {
- this.wait();// 因为等待在这里的其他操作set的线程不会再判断条件
- } catch (InterruptedException e) {}
- this.name = name + "--" + count++;
- System.out.println("生产者--" + this.name);
- flag = true;
- this.notifyAll();// notifyAll():唤醒其他所有线程,否则可能全部等待
- }
- public synchronized void out() {
- while (!flag)// 让被唤醒的线程再一次判断标记
- try {
- this.wait();// wait()冻结当前线程,只能try,不能抛
- } catch (InterruptedException e) {}
- System.out.println("消费者----"+ this.name);
- flag = false;
- this.notifyAll();// 因为如果用notify(),可能会只唤醒了本方线程
- }
- }
- class Producer implements Runnable {
- private Goods g; Producer(Goods g) {this.g = g;}
- public void run() { while (true) { g.set("商品"); }}}
- class Consumer implements Runnable {
- private Goods g; Consumer(Goods g) {this.g = g;}
- public void run() { while (true) { g.out(); }}}
- public class SunJingQi {
- public static void main(String[] args) { Goods g = new Goods();
- new Thread(new Producer(g)).start();
- new Thread(new Producer(g)).start();
- new Thread(new Consumer(g)).start();
- new Thread(new Consumer(g)).start();
- }}
复制代码
使用Lock的代码
- import java.util.concurrent.locks.Condition;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- class Goods {
- private String name;
- private int count = 1;
- private boolean flag = false;
- // Lock替代了synchronized方法和语句,Condition替代了Object监视器的方法
- private Lock lock = new ReentrantLock();
- private Condition condition_pro = lock.newCondition();
- private Condition condition_con = lock.newCondition();
- public void set(String name) throws InterruptedException {
- lock.lock();
- try {
- while (flag)
- condition_pro.await();
- this.name = name + "--" + count++;
- System.out.println("生产者--" + this.name);
- flag = true;
- condition_con.signal();// 只唤醒对方线程
- } finally {
- lock.unlock();
- }
- }
- public void out() throws InterruptedException {
- lock.lock();
- try {
- while (!flag)
- condition_con.await();
- System.out.println("消费者----" + this.name);
- flag = false;
- condition_pro.signal();// 只唤醒对方线程
- } finally {
- lock.unlock();
- }
- }
- }
复制代码 |