题目描述:有三个线程,交替输出A、B、C,各输出5次
一、Synchronized实现(wait/notifyAll)
package com.fuping3.printAsOrder;
public class PrintCharWithSyn {
private int stat=0;
public void printChar(String str,int waitFlag,int nextFlag){
synchronized (this){
while(stat!=waitFlag){
try {
//System.out.println(Thread.currentThread().getName()+"阻塞");
this.wait(1000*5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+":"+str);
stat=nextFlag;
this.notifyAll();
}
}
}
//测试代码
public static void main(String[] args) throws InterruptedException {
PrintCharWithSyn pt=new PrintCharWithSyn();
new Thread(()->{
for(int i=0;i<5;i++){
pt.printChar("A",0,1);
}
},"t1").start();
new Thread(()->{
for(int i=0;i<5;i++){
pt.printChar("B",1,2);
}
},"t2").start();
new Thread(()->{
for(int i=0;i<5;i++){
pt.printChar("C",2,0);
}
},"t3").start();
}
二、Lock实现(await/signal)
package com.fuping3.printAsOrder;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class PrintCharWithLock extends ReentrantLock{
public void printChar(String str,Condition curr,Condition next){
lock();
try{
curr.await();
System.out.println(Thread.currentThread().getName()+":"+str);
next.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
unlock();
}
}
}
//测试代码
public static void runWithLock() throws InterruptedException {
PrintCharWithLock ptLock=new PrintCharWithLock();
Condition c1=ptLock.newCondition();
Condition c2=ptLock.newCondition();
Condition c3=ptLock.newCondition();
new Thread(()->{
for(int i=0;i<5;i++){
ptLock.printChar("A",c1,c2);
}
},"t1").start();
new Thread(()->{
for(int i=0;i<5;i++){
ptLock.printChar("B",c2,c3);
}
},"t2").start();
new Thread(()->{
for(int i=0;i<5;i++){
ptLock.printChar("C",c3,c1);
}
},"t3").start();
/**
* 1、各线程进入后立即进入等待室,所以主线程需要唤醒c1
* 2、主线程需要等待一段时间,使各线程能进入等待室
*/
Thread.sleep(1000);
ptLock.lock();
try{
c1.signal();
}finally {
ptLock.unlock();
}
}
三、park/unpark实现
注意:
1、park/unpark此处用不到锁;
2、线程启动以后,park/unpark执行顺序无影响
package com.fuping3.printAsOrder;
import java.util.concurrent.locks.LockSupport;
public class PrintCharWithPark {
public void printChar(String str,Thread nextThread){
LockSupport.park();
System.out.println(Thread.currentThread().getName()+":"+str);
LockSupport.unpark(nextThread);
}
}
//测试代码
public class TestWithSynOrLock {
private static Thread t1,t2,t3;
public static void main(String[] args) throws InterruptedException {
PrintCharWithPark pt=new PrintCharWithPark();
t1=new Thread(()->{
for(int i=0;i<5;i++){
pt.printChar("A",t2);
}
},"t1");
t2=new Thread(()->{
for(int i=0;i<5;i++){
pt.printChar("B",t3);
}
},"t2");
t3=new Thread(()->{
for(int i=0;i<5;i++){
pt.printChar("C",t1);
}
},"t3");
t1.start();
t2.start();
t3.start();
LockSupport.unpark(t1);
}
}