https://blog.csdn.net/hefenglian/article/details/82596072
https://blog.csdn.net/Evankaka/article/details/80800081
1.使用join
如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B
2.使用CountDownLatch
await方法阻塞当前线程,当CountDownLatch减为0时就代表条件已成熟,所有因调用await方法而阻塞的线程都会被唤醒
3.使用阻塞队列,利用队列的FIFO特性
4.使用newSingleThreadExecutor内部,线程池的newSingleThreadExecutor内部使用一个容量不限的阻塞队列,同3类似
解决:3个线程1、2、3依次执行打印ABC,但是实际处理的时候不一定先执行线程1打印A,具体跟判断逻辑有关,比如先执行了线程3,但是run中判断满足条件才输出。
public class PrintABCByLockAndCondition {
private static Lock lock = new ReentrantLock();
private static Condition conditionA = lock.newCondition();
private static Condition conditionB = lock.newCondition();
private static Condition conditionC = lock.newCondition();
private static int status = 0;
public static void main(String[] args) {
new PrintABCByLockAndCondition().printABC();
}
public void printABC() {
ExecutorService service = Executors.newFixedThreadPool(3);
//线程的执行顺序跟提交顺序无关
service.execute(new RunnableC());
service.execute(new RunnableB());
service.execute(new RunnableA());
service.shutdown();
}
private class RunnableA implements Runnable {
@Override
public void run() {
try {
lock.lock();
while (true) {
while (status % 3 != 0) {//注意这里是不等于0,也就是说没轮到该线程执行,之前一直等待状态
conditionA.await();//释放了锁,进入阻塞等待,依赖C唤醒
}
System.out.print("A");
status++;
conditionB.signal(); // A执行完唤醒B线程
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
private class RunnableB implements Runnable {
@Override
public void run() {
try {
lock.lock();
while (true) {
while (status % 3 != 1) {
conditionB.await();
}
System.out.print("B");
status++;
conditionC.signal(); // B执行完唤醒C线程
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
private class RunnableC implements Runnable {
@Override
public void run() {
try {
lock.lock();
while (true) {
while (status % 3 != 2) {
conditionC.await();
}
System.out.println("C");
status++;
conditionA.signal(); // C执行完唤醒A线程
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class PrintABCByLock {
private static Lock lock = new ReentrantLock();
private static int status = 0;
public static void main(String[] args) {
new PrintABCByLock().printABC();
}
public void printABC() {
ExecutorService service = Executors.newFixedThreadPool(3);
//线程的执行顺序跟提交顺序无关
service.execute(new RunnableC());
service.execute(new RunnableB());
service.execute(new RunnableA());
service.shutdown();
}
private class RunnableA implements Runnable {
@Override
public void run() {
while (true) {
try {
lock.lock();
while (status % 3 == 0) {
System.out.print("A");
status++;
}
} finally {
lock.unlock();
}
}
}
}
private class RunnableB implements Runnable {
@Override
public void run() {
while (true) {
try {
lock.lock();
while (status % 3 == 1) {
System.out.print("B");
status++;
}
} finally {
lock.unlock();
}
}
}
}
private class RunnableC implements Runnable {
@Override
public void run() {
while (true) {
try {
lock.lock();
while (status % 3 == 2) {
System.out.println("C");
status++;
}
} finally {
lock.unlock();
}
}
}
}
}
public class PrintABCBySemaphore {
//信号量,表示可用的许可数量,用于控制同时容许访问的线程数量
public Semaphore s1 = new Semaphore(1);
public Semaphore s2 = new Semaphore(0);
public Semaphore s3 = new Semaphore(0);
public static void main(String[] args) {
new PrintABCBySemaphore().printABC();
}
public void printABC() {
ExecutorService exe = Executors.newFixedThreadPool(3);
exe.execute(new RunnableC());
exe.execute(new RunnableA());
exe.execute(new RunnableB());
exe.shutdown();
}
private class RunnableA implements Runnable {
@Override
public void run() {
while (true) {
try {
s1.acquire();//获取信号量,s1 - 1
System.out.print("A");
s2.release();//释放信号量,s2 + 1
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private class RunnableB implements Runnable {
@Override
public void run() {
while (true) {
try {
s2.acquire();//获取信号量,s2 - 1
System.out.print("B");
s3.release();//释放信号量,s3 + 1
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private class RunnableC implements Runnable {
@Override
public void run() {
while (true) {
try {
s3.acquire();//获取信号量,s3 - 1
System.out.println("C");
s1.release();//释放信号量,s1 + 1
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class PrintABCByAtomic {
private AtomicInteger status = new AtomicInteger(0);
public static void main(String[] args) {
new PrintABCByAtomic().printABC();
}
public void printABC() {
ExecutorService service = Executors.newFixedThreadPool(3);
//线程的执行顺序跟提交顺序无关
service.execute(new RunnableC());
service.execute(new RunnableB());
service.execute(new RunnableA());
service.shutdown();
}
private class RunnableA implements Runnable {
@Override
public void run() {
while (true) {
if (status.get() % 3 == 0) {
System.out.print("A");
status.getAndIncrement();
}
}
}
}
private class RunnableB implements Runnable {
@Override
public void run() {
while (true) {
if (status.get() % 3 == 1) {
System.out.print("B");
status.getAndIncrement();
}
}
}
}
private class RunnableC implements Runnable {
@Override
public void run() {
while (true) {
if (status.get() % 3 == 2) {
System.out.println("C");
status.getAndIncrement();
}
}
}
}
}