线程间通信:
多个线程在处理同一资源,但是
等待唤醒机制
涉及的方法:
1、wait() 让线程处于冻结状态,被wait的线程会被存储到线程池中。
2、notify() 唤醒线程池中的一个线程(任意)
3、notifyAll() 唤醒线程池中的所有线程、、
这些方法都必须定义在同步中,
因为这些方法是用于操作线程状态的方法。
必须明确到底操作的那个锁上的线程。
为什么操作线程的方法wait notify notifyAll定义在了Object中。
因为这些方法是监视器方法,监视器其实就是锁。
锁可以是任意的对象,任意的对象调用的方法一定定义在Object类中。
package com.pzq.thread; public class SyncDemo3 { public static void main(String[] args) { Resource resource = new Resource(); Input input = new Input(resource); OutPut outPut = new OutPut(resource); Thread threadInput = new Thread(input); Thread threadOuput = new Thread(outPut); threadInput.start(); threadOuput.start(); } } class Input implements Runnable { Resource r; public Input(Resource r) { 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 = "mike"; r.sex = "nan"; } else { r.name = "丽丽"; r.sex = "女女女女女女女"; } r.flag = true; r.notify(); } x = (x + 1) % 2; } } } class OutPut implements Runnable { Resource r; public OutPut(Resource r) { 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(); } } } } class Resource { String name; String sex; boolean flag = false; public Resource() { } public Resource(String name, String sex) { this.name = name; this.sex = sex; } }
package com.pzq.thread; public class SyncDemo3 { public static void main(String[] args) { Resource resource = new Resource(); Input input = new Input(resource); OutPut outPut = new OutPut(resource); Thread threadInput = new Thread(input); Thread threadOuput = new Thread(outPut); threadInput.start(); threadOuput.start(); } } class Input implements Runnable { Resource r; public Input(Resource r) { this.r = r; } @Override public void run() { int x = 0; while (true) { if (x == 0) { r.set("mike", "nan"); } else { r.set("丽丽", "=========女"); } x = (x + 1) % 2; } } } class OutPut implements Runnable { Resource r; public OutPut(Resource r) { this.r = r; } @Override public void run() { while (true) { r.out(); } } } class Resource { private String name; private String sex; private boolean flag = false; public Resource() { } 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) { e.printStackTrace(); } } System.out.println(this.name + "....." + this.sex); flag = false; this.notify(); } }
package com.pzq.thread; public class SyncDemo4 { public static void main(String[] args) { Resource2 resource = new Resource2(); Producter input = new Producter(resource); Customer outPut = new Customer(resource); Thread threadInput = new Thread(input); Thread threadOuput = new Thread(outPut); threadInput.start(); threadOuput.start(); } } class Producter implements Runnable { Resource2 r; public Producter(Resource2 r) { this.r = r; } @Override public void run() { while (true) { r.set("烤鸭"); } } } class Customer implements Runnable { Resource2 r; public Customer(Resource2 r) { this.r = r; } @Override public void run() { while (true) { r.out(); } } } class Resource2 { private String name; private boolean flag = false; private int count = 1; public Resource2() { } public synchronized void set(String name) { if (flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name + count; count++; System.out.println(Thread.currentThread().getName() + "生产者+++" + this.name); flag = true; this.notify(); } public synchronized void out() { if (!flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "消费者" + "=================" + this.name); flag = false; this.notify(); } }
if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
while判断标记,解决了线程获取执行权后,是否要运行
notify只能唤醒一个线程,如果本方唤醒了本方,就没有意义了。而且 while判断标记+notify会导致死锁。
notifyAll解决了,本方线程一定会唤醒对方线程。
package com.pzq.thread; public class SyncDemo4 { public static void main(String[] args) { Resource2 resource = new Resource2(); Producter input = new Producter(resource); Customer outPut = new Customer(resource); Thread threadInput1 = new Thread(input); Thread threadInput2 = new Thread(input); Thread threadInput3 = new Thread(input); Thread threadOuput1 = new Thread(outPut); Thread threadOuput2 = new Thread(outPut); Thread threadOuput3 = new Thread(outPut); Thread threadOuput4 = new Thread(outPut); Thread threadOuput5 = new Thread(outPut); threadInput1.start(); threadInput2.start(); threadInput3.start(); threadOuput1.start(); threadOuput2.start(); threadOuput3.start(); threadOuput4.start(); threadOuput5.start(); } } class Producter implements Runnable { Resource2 r; public Producter(Resource2 r) { this.r = r; } @Override public void run() { while (true) { r.set("烤鸭"); } } } class Customer implements Runnable { Resource2 r; public Customer(Resource2 r) { this.r = r; } @Override public void run() { while (true) { r.out(); } } } class Resource2 { private String name; private boolean flag = false; private int count = 1; public Resource2() { } public synchronized void set(String name) { while (flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.name = name + count; count++; System.out.println(Thread.currentThread().getName() + "生产者+++" + this.name); flag = true; this.notifyAll(); } public synchronized void out() { while (!flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "消费者" + "=================" + this.name); flag = false; this.notifyAll(); } }
原文:https://www.cnblogs.com/qiangge-python/p/11067391.html