实现一个场景
三个线程分别交替打印A、B、C,打印100次。
基于synchronized 锁的实现方式
public class test {
private static Integer num = 0;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (num < 100){
synchronized (num){
if (num%3==0&&num<=99){
System.out.println("A");
num++;
}
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (num < 100){
synchronized (num){
if (num%3==1&&num<=99){
System.out.println("B");
num++;
}
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (num < 100){
synchronized (num){
if (num%3==2&&num<=99){
System.out.println("C");
num++;
}
}
}
}
}).start();
}
}
基于Lock锁的Condition实现线程通信
package leetcode.leetcode11;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class test06 {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
new Thread(new Runnable() {
@Override
public void run() {
int a = 0;
while (a<34){
lock.lock();
a++;
System.out.println("A");
conditionB.signal();
try {
conditionA.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
int a = 0;
while (a<33){
lock.lock();
a++;
System.out.println("B");
conditionC.signal();
try {
conditionB.await();
if (a==33) conditionC.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
int a = 0;
while (a<33){
a++;
lock.lock();
System.out.println("C");
conditionA.signal();
try {
conditionC.await();
if (a==33) conditionA.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
}
}).start();
}
}
注意这里面还是需要注意一下的,比如实现打印完成之后线程结束,这里面就要进行if判断了if (a==33) conditionA.signal();
因为如果不判断的话第一个线程执行完之后唤醒第二个,第二个执行完结束了,没有办法唤醒第三个等待的线程了。
对第二种方式进行重构优化
package leetcode.leetcode11;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class test06 {
static class Runner implements Runnable{
ReentrantLock lock;
Condition now_condition;
Condition next_condition;
int num ;
String ss;
int a = 0;
@Override
public void run() {
while (a<num){
lock.lock();
System.out.println(ss);
a++;
next_condition.signal();
try {
now_condition.await();
if (a==33) next_condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unlock();
}
}
public Runner(ReentrantLock lock, Condition now_condition, Condition next_condition, int num, String ss) {
this.lock = lock;
this.now_condition = now_condition;
this.next_condition = next_condition;
this.num = num;
this.ss = ss;
}
}
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
Thread t1 = new Thread(new Runner(lock,conditionA,conditionB,34,"A"));
Thread t2 = new Thread(new Runner(lock,conditionB,conditionC,33,"B"));
Thread t3 = new Thread(new Runner(lock,conditionC,conditionA,33,"C"));
t1.start();
t2.start();
t3.start();
}
}