书接上文。上文我们介绍了两个线程的情况下,如何交替执行,如何使用wait notify等object 方法。本文我们主要介绍,如果线程数大于2的情况下,如何让线程交替执行。本次我们使用了ReentrantLock,并且通过Condition来控制线程的等待与唤醒。condition.await()方法等同于obj.wait(). condition.signal()等同于obj.notify()方法。signalAll()与notifyAll()等同,这里我们不做过多介绍。下面开始上代码。欢迎各位指正。
package com.example.feignclient.process.condition;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test1 extends Thread {
private Test test;
private Condition condition2;
private Condition condition1;
private Lock lock;
public Test1(Test test, Condition condition1, Condition condition2, Lock lock) {
this.test = test;
this.condition2 = condition2;
this.condition1 = condition1;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
try {
while (test.ticket > 0) {
if (test.ticket > 0) {
test.ticket = test.ticket - 1;
System.out.println(Thread.currentThread().getName() + "车票:" + test.ticket);
}
condition2.signal();
condition1.await();
}
if(test.ticket==0){
condition2.signalAll();
}
} catch (Exception e) {
e.printStackTrace();
lock.unlock();
} finally {
lock.unlock();
}
}
}
package com.example.feignclient.process.condition;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class Test2 extends Thread {
private Test test;
private Condition condition1;
private Condition condition2;
private Lock lock;
public Test2(Test test, Condition condition1, Condition condition2, Lock lock) {
this.test = test;
this.condition1 = condition1;
this.condition2 = condition2;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
try {
while (test.ticket > 0) {
if (test.ticket > 0) {
test.ticket = test.ticket - 1;
System.out.println(Thread.currentThread().getName() + "车票:" + test.ticket);
}
condition2.signal();
condition1.await();
}
if (test.ticket == 0) {
condition2.signalAll();
}
} catch (Exception e) {
e.printStackTrace();
lock.unlock();
} finally {
lock.unlock();
}
}
}
package com.example.feignclient.process.condition;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
public class Test3 extends Thread {
private Test test;
private Condition condition2;
private Condition condition3;
private Lock lock;
public Test3(Test test, Condition condition2, Condition condition3, Lock lock) {
this.test = test;
this.condition2 = condition2;
this.condition3 = condition3;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
try {
while (test.ticket > 0) {
if (test.ticket > 0) {
test.ticket = test.ticket - 1;
System.out.println(Thread.currentThread().getName() + "车票:" + test.ticket);
}
condition3.signal();
condition2.await();
}
if(test.ticket==0){
condition3.signalAll();
}
} catch (Exception e) {
e.printStackTrace();
lock.unlock();
} finally {
lock.unlock();
}
}
}
package com.example.feignclient.process.condition;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
public int ticket = 10;
public static void main(String[] args)throws Exception {
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
Test test = new Test();
Test1 t1 = new Test1(test,condition1,condition2,lock);
Test2 t2 = new Test2(test,condition2,condition3,lock);
Test3 t3 = new Test3(test,condition3,condition1,lock);
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
System.out.println(test.ticket);
}
}