多线程之间的交互
像在一个参数版本中,中断和虚假唤醒是可能的,并且该方法应该始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
不能使用if来判断,应该使用while。
在多线程中判断使用while
package cn.zh.juc1205;
class Aircondition {
private int number = 0;
public synchronized void increment() throws Exception {
//判断
while (number != 0) {
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName()+"\t" +number);
//通知
this.notifyAll();
}
public synchronized void decrement() throws Exception {
//判断
while (number == 0) {
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"\t" +number);
//通知
this.notifyAll();
}
}
/**
*题目:现在两个线程,可以操作初始值为零的一个变量,
* 实现一个线程对该变量加1,一个线程对该变量减1,
* 实现交替,来10轮,变量初始值为零
* 1.高内聚低耦合前提下,线程操作资源类
* 2.判断/干活/通知
* 3.防止虚假唤醒
*/
public class ProdConsumerDemo04 {
public static void main(String[] args) throws Exception {
Aircondition aircondition = new Aircondition();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
aircondition.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
aircondition.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
aircondition.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 1; i <= 10; i++) {
try {
aircondition.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"D").start();
}
}
package cn.zh.juc1205;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class ShareData {
private int number = 1;//A:1 B:2 C:3定义标志位
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public void print5() {
lock.lock();
try {
//1.判断
while (number != 1) {
c1.await();
}
//2.打印五次
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
//3.通知 如何通知第二个
number = 2;
c2.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10() {
lock.lock();
try {
//1.判断
while (number != 2) {
c2.await();
}
//2.打印五次
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
//3.通知 如何通知第二个
number = 3;
c3.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print15() {
lock.lock();
try {
//1.判断
while (number != 3) {
c3.await();
}
//2.打印五次
for (int i = 0; i < 15; i++) {
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
//3.通知 如何通知第二个
number = 1;
c1.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* 备注多线程之间按顺序调用 实现A->B->C
* 三个线程启动,要求如下:
* AA打印5次,BB打印10次,CC打印15次
* 接着
* AA打印5次,BB打印10次,CC打印15次
*
*/
public class ConditionDemo {
public static void main(String[] args) {
ShareData shareData = new ShareData();
new Thread(()->{
for (int i = 1;i <= 10; i++) {
shareData.print5();
}
},"A").start();
new Thread(()->{
for (int i = 1;i <= 10; i++) {
shareData.print10();
}
},"B").start();
new Thread(()->{
for (int i = 1;i <= 10; i++) {
shareData.print15();
}
},"C").start();
}
}
还没有评论,来说两句吧...