java多线程实现有序输出ABC
3个线程,线程1输出A,线程2输出B,线程3输出C,让这个3个线程循环有序地输出ABCABC…
看到这个题目,感觉很有意思,问题的本质是在多线程执行环境,控制线程的执行顺序,实现的方式有非常多种,本质上需要解决Java多线程环境下的线程执行的同步和利用锁机制来控制线程的执行顺序。
方式1:利用synchronized
这种方式也就是使用java内置的monitor机制,配合wait和notifyAll,代码如下:
(1)利用volatile做线程间资源的同步访问,同时作为线程调度的标志;
(2)利用notifyAll来唤醒其他等待当前的monitor资源的线程;
publicclassThreadOrderWithSync{
privatevolatileintflag='A';
privatefinalstaticObjectLOCK=newObject();
Runnablea=()->{
while(true){
synchronized(LOCK){
if(flag=='A'){
System.out.println("A");
flag='B';
//letotherthreadracetogetthemonitor
LOCK.notifyAll();
}else{
try{
LOCK.wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
};
Runnableb=()->{
while(true){
synchronized(LOCK){
if(flag=='B'){
System.out.println("B");
flag='C';
//letotherthreadracetogetthemonitor
LOCK.notifyAll();
}else{
try{
LOCK.wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
};
Runnablec=()->{
while(true){
synchronized(LOCK){
if(flag=='C'){
System.out.println("C");
flag='A';
//letotherthreadracetogetthemonitor
LOCK.notifyAll();
}else{
try{
LOCK.wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
};
publicvoidrunTest(){
Threadta=newThread(a);
Threadtb=newThread(b);
Threadtc=newThread(c);
ta.start();
tb.start();
tc.start();
}
publicstaticvoidmain(String[]args){
ThreadOrderWithSyncsync=newThreadOrderWithSync();
sync.runTest();
}
}
方式2:利用并发包ReentrantLock和Condition的锁机制
上面方式1的synchronized机制,因为当前的所有线程都争用同一个monitor资源,因此只能通过notifyAll来通知其他线程来加锁,因此每次都会出现racecondition,但是,通过ReentrantLock的Condition,我们可以精确控制,下一个该唤醒signal的线程是哪一个(因为我们知道执行的顺序是A->B->C的循环),相比synchronized的机制,Condition机制可以更精细化线程的调度设计,代码示例如下:
/**
*@authorxijin.zengcreatedon2018/8/31
*Thradsruningorder:A->B->C
*/
publicclassThreadOrderWithCondition{
privatestaticfinalReentrantLockLOCK=newReentrantLock();
privatestaticfinalConditionC_A=LOCK.newCondition();
privatestaticfinalConditionC_B=LOCK.newCondition();
privatestaticfinalConditionC_C=LOCK.newCondition();
/**
*initforAtorunfirst
*/
privatevolatileintflag='A';
Runnablea=()->{
while(true){
LOCK.lock();
if(flag=='A'){
System.out.println("A");
flag='B';
//signalBtorun
C_B.signal();
}else{
try{
//blockandwaitsignaltoinvoke
C_A.await();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
LOCK.unlock();
}
};
Runnableb=()->{
while(true){
LOCK.lock();
if(flag=='B'){
System.out.println("B");
flag='C';
//signalCtorun
C_C.signal();
}else{
try{
//blockandwaitsignaltoinvoke
C_B.await();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
LOCK.unlock();
}
};
Runnablec=()->{
while(true){
LOCK.lock();
if(flag=='C'){
System.out.println("C");
flag='A';
//signalAtorun
C_A.signal();
}else{
try{
//blockandwaitsignaltoinvoke
C_C.await();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
LOCK.unlock();
}
};
publicvoidrunTest(){
ThreadthreadA=newThread(a);
ThreadthreadB=newThread(b);
ThreadthreadC=newThread(c);
threadA.start();
threadB.start();
threadC.start();
}
publicstaticvoidmain(String[]args){
ThreadOrderWithConditiono=newThreadOrderWithCondition();
o.runTest();
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。