使用不同线程时我们的源代码顺序为 运行
Order in which our source code is run when using different threads
刚开始学习Java的时候,了解到code是从top读取的 到 底部 。不需要编写代码来解释这个解释,我想你们都明白了。
但是当我使用 multi-threading
时会发生什么?假设我有这个简单的例子:
public class Tester {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
executorService.execute(new WorkingClass());
}
System.out.println("rest od code..");
executorService.shutdown();
}
}
class WorkingClass implements Runnable{
@Override
public void run() {
System.out.println("working");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
我正在使用 singleThreadExecutor
,因此 1 个线程 应该完成那些 5 个任务。我原以为我的 for 循环 会先 运行,在 console[= 中打印 "rest od code.."
之前至少打印一个 "working"
39=]。我错了。我的结果总是这样:
rest od code..
working
working
working
working
working
谁能告诉我为什么 'rest of code'
之前 console 中至少打印了一个 'working'
?代码 运行 是否有可能如此之快以至于它在到达 ('rest of code') 之前没有机会实际 运行 任何 run() method
?
[注意]任何编辑都将不胜感激,以帮助改进这个问题。
不同线程运行独立。无法保证您的主线程与其创建的任何 'Runnables' 之间的相对顺序。
这与代码是否'read'从上到下无关;这不是执行的有用概念。这是 non-top-to-bottom 执行的简单 non-thread 示例:
void method1() {
method2();
System.out.println("one");
}
void method2() {
System.out.println("two");
}
回到手头的问题:您会注意到 'execute' 的 documentation 指的是 运行 在 'some time in the future' 处运行 Runnable。
实际上,这可能类似于将一个条目放入队列然后唤醒一个线程。启动线程并 运行ning 通常需要比 straight-line 代码路径更多的机器指令。
所以,是的,你的 'runs so fast' 解释是 more-or-less 的,除了 'so fast' 并不是真的快得让人眼花缭乱。
线程并发执行(主线程和工作线程),尝试在main方法中的println之前暂停主线程执行一小会儿,结果会有所不同。
Thread.sleep(1000);
System.out.println("rest od code..");
executorService.shutdown();
重复 运行 并且您的工作线程在主线程暂停时执行的可能性很大。
期待内存一致性效果:
“在将 Runnable 或 Callable 任务提交给 ExecutorService 之前线程中的操作 happen-before 该任务采取的任何操作,进而 happen-before 结果通过 Future.get()"
刚开始学习Java的时候,了解到code是从top读取的 到 底部 。不需要编写代码来解释这个解释,我想你们都明白了。
但是当我使用 multi-threading
时会发生什么?假设我有这个简单的例子:
public class Tester {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
executorService.execute(new WorkingClass());
}
System.out.println("rest od code..");
executorService.shutdown();
}
}
class WorkingClass implements Runnable{
@Override
public void run() {
System.out.println("working");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
我正在使用 singleThreadExecutor
,因此 1 个线程 应该完成那些 5 个任务。我原以为我的 for 循环 会先 运行,在 console[= 中打印 "rest od code.."
之前至少打印一个 "working"
39=]。我错了。我的结果总是这样:
rest od code..
working
working
working
working
working
谁能告诉我为什么 'rest of code'
之前 console 中至少打印了一个 'working'
?代码 运行 是否有可能如此之快以至于它在到达 ('rest of code') 之前没有机会实际 运行 任何 run() method
?
[注意]任何编辑都将不胜感激,以帮助改进这个问题。
不同线程运行独立。无法保证您的主线程与其创建的任何 'Runnables' 之间的相对顺序。
这与代码是否'read'从上到下无关;这不是执行的有用概念。这是 non-top-to-bottom 执行的简单 non-thread 示例:
void method1() {
method2();
System.out.println("one");
}
void method2() {
System.out.println("two");
}
回到手头的问题:您会注意到 'execute' 的 documentation 指的是 运行 在 'some time in the future' 处运行 Runnable。
实际上,这可能类似于将一个条目放入队列然后唤醒一个线程。启动线程并 运行ning 通常需要比 straight-line 代码路径更多的机器指令。
所以,是的,你的 'runs so fast' 解释是 more-or-less 的,除了 'so fast' 并不是真的快得让人眼花缭乱。
线程并发执行(主线程和工作线程),尝试在main方法中的println之前暂停主线程执行一小会儿,结果会有所不同。
Thread.sleep(1000);
System.out.println("rest od code..");
executorService.shutdown();
重复 运行 并且您的工作线程在主线程暂停时执行的可能性很大。
期待内存一致性效果:
“在将 Runnable 或 Callable 任务提交给 ExecutorService 之前线程中的操作 happen-before 该任务采取的任何操作,进而 happen-before 结果通过 Future.get()"