4、多线程(等待唤醒机制)(synchronized & Condition)两种写法

来源:互联网 发布:淘宝假发 编辑:程序博客网 时间:2024/06/16 21:37

synchronized 

wait();

notify();
notifyAll();
都使用在同步中,因为要对持有监视器(锁)的线程操作
所以要使用在同步中,因为只有在同步中才有锁

为什么这些操作线程的方法要定义在Object类中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁。
只有同一个锁上的被等待线程,可以被同一个notify唤醒。
不可以对不同锁中的线程唤醒
也就是等待和唤醒必须是同一个锁。

而锁可以是任意对象,所以被任意对象调用的方法定义在Object中

public class InputOutputDemo {public static void main(String[] args) {Res r = new Res();Input in = new Input(r);Output out = new Output(r);Thread t1 = new Thread(in);Thread t2 = new Thread(out);t1.start();t2.start();}}class Res {String name;String sex;boolean flag = false;}class Input implements Runnable {Res r = new Res();int x = 0;Input(Res r) {this.r = r;}public void run() {while (true) {synchronized (r) {if (r.flag)// 判断是否为真{try {wait();} catch (Exception e) {}// 冻结}if (x == 0) {r.name = "胡平燕";r.sex = "男";} else {r.name = "Painter";r.sex = "man";}x = (x + 1) % 2;r.flag = true;r.notify();// 唤醒}}}}class Output implements Runnable {Res r = new Res();Output(Res r) {this.r = r;}public void run() {synchronized (r) {if (!r.flag) {try {r.wait();} catch (Exception e) {}// 冻结}System.out.println(r.name + "......." + r.sex);r.flag = false;r.notify();// 唤醒}}}


Condition

Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。下面将上面写过的一个线程通信的例子替换成用Condition实现

package com.Painter.suo; import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock; public class InputOutputDemo {     public static void main(String[] args)     {        Res r = new Res();        new Thread(new Input(r)).start();        new Thread(new Output(r)).start();    }} class Res{    private String name;    private String sex;    private Lock lock = new ReentrantLock();    private Condition condition_1 = lock.newCondition();    private Condition condition_2 = lock.newCondition();    private boolean flag = false;    public void set(String name,String sex) throws InterruptedException    {        lock.lock();        while(flag)        {            try            {                condition_1.await();                this.name = name;                this.sex = sex;                flag = true;                condition_2.signal();            }            finally            {                lock.unlock();            }         }           }    public void out() throws InterruptedException     {        lock.lock();        try        {            condition_2.await();            System.out.print(name+".........."+sex);            flag = true;            condition_1.signal();        }        finally        {            lock.unlock();        }    }}class Input implements Runnable{    Res r = new Res();    int x =0;    Input(Res r)    {        this.r = r;    }    public void run()    {        while (true)         {            if(x==0)            {                try                {                    r.set("胡平燕","男");                }                 catch (InterruptedException e)                 {                                       e.printStackTrace();                }            }            else            {                try                {                    r.set("Painter","man");                }                 catch (InterruptedException e)                 {                                       e.printStackTrace();                }             }            x=(x+1)%2;        }    }}class Output implements Runnable{    Res r = new Res();    Output(Res r)     {        this.r = r;    }    public void run()     {        try        {            r.out();        }         catch (InterruptedException e)         {            e.printStackTrace();        }       }}



0 0