解释:
When two or more threads need access to a shared resource, they need some way to ensure that the resource will be used by only one thread at a time.
The process by which this synchronization is achieved is called threadsynchronization.
The synchronized keyword in Java creates a block of code referred to as a critical section. Every Java object with a critical section of code gets a lock associated with the object. To enter a critical section, a thread needs to obtain the corresponding object‘slock.
This is the general form of the synchronized statement:
synchronized(object) { // statements to be synchronized }
Here, object is a reference to the object being synchronized. A synchronized block ensures that a call to a method that is a member of object occurs only after the current thread has successfully entered object‘s monitor.
/**
* 线程间通讯:
* 其实就是多个线程在操作同一个资源
* 但是操作的动作不同
*/
wait, notify, notifyAll()
都是用在同步中,因为要对持有监视器(锁)的线程操作。
所以要使用在同步中,因为只有同步才具有锁。
为什么这些操作线程的方法,要定义在object类中呢?
因为这些方法在操作同步中线程时,都必须要标识他们所操作线程持有的锁,
只有同一个锁上得被等待线程,可以被统一个锁上得notify唤醒。
不可以对不同锁中的线程进行唤醒。
也就是说,等待和唤醒必须是同一个锁。
而锁可以是任意对象,所以可以被任意对象调用的方法(wait, notify,notifyAll)定义在object类中
举例:Input类用于,传入内容,Output类用于传出内容,由于传输的数据是共享的,所以将这个传输的数据对象作为“锁”。
等待====》唤醒
为了能够输入线程,和输出线程一次只运行一个线程,于是:输入线程工作,输出等待,输入线程等待,输出线程工作。
public class Input implements Runnable { private Res r; public Input(Res r) { super(); this.r = r; } @Override public void run() { int x = 0; while (true) { synchronized (r) { if (r.flag) try { r.wait(); } catch (InterruptedException e) { e.printStackTrace(); } if (x == 0) { r.name = "LI"; r.sex = "femal"; } else { r.name = "李雷"; r.sex = "男"; } x = (x + 1) % 2; r.flag = true; r.notify(); } } } }
public class Output implements Runnable { private Res r; public Output(Res r) { super(); this.r = r; } @Override public void run() { while (true) { synchronized (r) { if (!r.flag) try { r.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(r.name + "," + r.sex); r.flag = false; r.notify(); } } } }
public class Res { String name; String sex; boolean flag = false; }
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(); } }
public class Res { private String name; private String sex; private boolean flag = false; public synchronized void set(String name, String sex) { if (flag) try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } this.name = name; this.sex = sex; flag = true; this.notify(); } public synchronized void out() { if (!flag) try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(name + "..." + sex); flag = false; this.notify(); } }
public class Input implements Runnable { private Res r; public Input(Res r) { super(); this.r = r; } @Override public void run() { int x = 0; while (true) { if (x == 0) r.set("Li", "female"); else r.set("李雷", "男"); x = (x + 1) % 2; } } }
public class Output implements Runnable { private Res r; public Output(Res r) { super(); this.r = r; } @Override public void run() { while (true) { r.out(); } } }
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(); } }
Thread线程间通讯-wait,notify,布布扣,bubuko.com
原文:http://blog.csdn.net/zqx198810/article/details/20957469