java多线程笔记--顺序执行
Posted SingleOneMan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程笔记--顺序执行相关的知识,希望对你有一定的参考价值。
java多线程笔记–多线程顺序执行
文章目录
参考: https://www.cnblogs.com/xiaoxi/p/8035725.html
https://blog.csdn.net/hefenglian/article/details/82596072
https://blog.csdn.net/Evankaka/article/details/80800081
1.java多线程笔记–顺序执行
1.使用join
如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B
2.使用CountDownLatch
await方法阻塞当前线程,当CountDownLatch减为0时就代表条件已成熟,所有因调用await方法而阻塞的线程都会被唤醒
3.使用阻塞队列,利用队列的FIFO特性
4.使用newSingleThreadExecutor内部,线程池的newSingleThreadExecutor内部使用一个容量不限的阻塞队列,同3类似
2.java多线程笔记–循环顺序打印问题
解决:3个线程1、2、3依次执行打印ABC,但是实际处理的时候不一定先执行线程1打印A,具体跟判断逻辑有关,比如先执行了线程3,但是run中判断满足条件才输出。
2.1通过Lock、3个Condition的等待唤醒机制和状态变量判断,来控制3个线程输出顺序
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();
2.2通过Lock和状态变量判断,来控制3个线程输出顺序
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();
2.3通过3个信号量,每个信号量的最大许可为1,来控制3个输出顺序
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();
2.4通过Atomic原子自增和3个线程的判断逻辑,来控制3个线程输出顺序
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();
以上是关于java多线程笔记--顺序执行的主要内容,如果未能解决你的问题,请参考以下文章