Lock版的生产者消费者的实现及问题
Lock版的生产者消费者的实现及问题
synchronized Lock Condition里面的
wait await
notifyAll signalAll
相对应
package com.example.juc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
public static void main(String[] args) {
A1 a = new A1();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
a.increase();
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
a.decrease();
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
a.increase();
}
}, "C").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
a.decrease();
}
}, "D").start();
}
}
class A1 {
private int num;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public void increase() {
lock.lock();
try {
// 等待
while (num != 0) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//
System.out.println(Thread.currentThread().getName() + "-->" + ++num);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void decrease() {
lock.lock();
try {
// 等待
while (num == 0) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//
System.out.println(Thread.currentThread().getName() + "-->" + --num);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
A-->1
B-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
C-->1
D-->0
问题:怎么让几个线程顺序执行呢?
package com.example.juc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestOrderLock {
public static void main(String[] args) {
Data data = new Data();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
data.printA();
}
}, "A").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
data.printB();
}
}, "B").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
data.printC();
}
}, "C").start();
}
}
class Data {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
private int num = 1;
public void printA() {
lock.lock();
try {
if (num != 1) {
condition1.await();
}
System.out.println(Thread.currentThread().getName() + "->AAAAAAAAAA");
num = 2;
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printB() {
lock.lock();
try {
if (num != 2) {
condition2.await();
}
System.out.println(Thread.currentThread().getName() + "->BBBBBBBB");
num = 3;
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printC() {
lock.lock();
try {
if (num != 3) {
condition3.await();
}
System.out.println(Thread.currentThread().getName() + "->CCCCCCCCCCC");
num = 1;
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC
A->AAAAAAAAAA
B->BBBBBBBB
C->CCCCCCCCCCC