java多线程保证顺序执行
前言
举例说明 比如要去冰箱里面拿牛奶,那么正常步骤是这样的。
1、打开冰箱
2、拿出牛奶
3、关上冰箱
代码实现是这样的:
public static void main(String[] args) {
Thread A = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("打开冰箱");
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("拿出牛奶");
}
});
Thread C = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("关上冰箱");
}
});
A.start();
B.start();
C.start();
}
但是我们运行之后会发现结果居然是这样的。什么鬼。
有小伙伴会问 代码执行不是由上往下的吗,我应该先做开冰箱的操作啊。
那是因为多线程的执行和线程写的前后顺序无关,而是和CPU中的线程调度有关。
线程是没有执行顺序的, 哪个线程抢到执行权,就哪个执行,其他线程等待。
保证线程顺序执行的方法一:
通过thread.join()方法
代码实现如下:
public static void main(String[] args) {
Thread A = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("打开冰箱");
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
try {
A.join();
System.out.println("拿出牛奶");
} catch (Exception e) {
}
}
});
Thread C = new Thread(new Runnable() {
@Override
public void run() {
try {
B.join();
System.out.println("关上冰箱");
} catch (Exception e) {
}
}
});
A.start();
B.start();
C.start();
}
另外也可以在启动线程的时候顺序的控制
public static void main(String[] args) {
try {
Thread A = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("打开冰箱");
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("拿出牛奶");
}
});
Thread C = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("关上冰箱");
}
});
A.start();
A.join();
B.start();
B.join();
C.start();
}
catch (Exception e)
{
}
}
保证线程顺序执行的方法二:
使用单线程化的线程池newSingleThreadExecutor
特点就是只有一个核心线程,无非核心线程,执行完立即回收。
注意提交时候的顺序。
public static void main(String[] args) {
try {
ExecutorService executor = Executors.newSingleThreadExecutor();
Thread A = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("打开冰箱");
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("拿出牛奶");
}
});
Thread C = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("关上冰箱");
}
});
executor.submit(A);
executor.submit(B);
executor.submit(C);
executor.shutdown();
}
catch (Exception e)
{
}
}
除了这两种之外,也还有其他的方法,比如借助CountDownLatch等等。
参考这篇文章 https://blog.csdn.net/m0_37825219/article/details/108962899
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)