Java 为什么我的输入显示一个线程在另一个线程之后执行,而不是同时执行?
我研究了线程的概念,发现它是让代码同时在两个进程中运行。这是我的密码Java 为什么我的输入显示一个线程在另一个线程之后执行,而不是同时执行?,java,multithreading,Java,Multithreading,我研究了线程的概念,发现它是让代码同时在两个进程中运行。这是我的密码 public class Connor extends Thread{ public void run() { for(int i=0; i< 10; i ++){ System.out.println("Hello " + i); } public static void main(String[] args){ Connor runn
public class Connor extends Thread{
public void run() {
for(int i=0; i< 10; i ++){
System.out.println("Hello " + i);
}
public static void main(String[] args){
Connor runner1 = new Connor();
Connor runner2 = new Connor();
runner1.start();
runner2.start();
}
}
公共类Connor扩展线程{
公开募捐{
对于(int i=0;i<10;i++){
System.out.println(“Hello”+i);
}
公共静态void main(字符串[]args){
Connor runner1=新Connor();
Connor runner2=新Connor();
runner1.start();
runner2.start();
}
}
和我的输出
看起来这两个线程是同时开始的(两个进程分开,由两个前导的0表示),但是一个线程执行(1-9),然后另一个线程执行(1-9)。它们不也应该交织在一起(1,1,2,2,…)bc线程都打印到控制台。我研究并发现start是正确的方法,因为它告诉thread类在另一个线程中执行run方法。有人能解释我为什么得到这个输出吗?你的代码看起来很好。我猜你的线程不会并行运行,只是因为它们终止为fast。更改loop限制在10到1000之间,您将看到效果
启动线程本身是一项相对繁重的操作。您先编写代码启动第一个线程,然后再启动第二个线程。启动的第一个线程在第二个线程有机会开始执行其业务逻辑之前终止。假设您有十个任务需要做,而您的妹妹有十个任务需要做,而您只有一个e car。你每次出差后都会把车带回来并更换驱动程序吗?当然不会。那效率会非常低。每个线程基本上只需要输出流。因此,将它们紧密地交织在一起是荒谬的。如果是多线程,则无法保证处理器a为哪个线程分配了运行时间nd在这种情况下,结果是不可预测的,并且将为每次运行生成不同的输出 如果您正在寻找所需的输出,则需要同步块。使用
wait
和notify
可以轻松实现
请直接从Oracle官方网站查看以下课程:
- 阅读更多关于并发的信息
- 阅读更多关于线程、锁和同步的信息
等待
&通知
必须在已同步的
块内调用,并且可以调用同步的同一对象
示例代码:(读取内联注释)
为什么我的输入显示一个线程在另一个线程之后执行,而不是同时执行
一般的解释是线程调度是不可预测的。交错可能发生……也可能不发生。这是Java线程的基础(事实上也是大多数其他语言的线程)
如果您需要线程执行以完全可预测的方式交错,那么您需要实现某种握手机制,其中一个线程等待另一个线程执行某项操作,然后继续执行。但这很复杂,通常无法达到使用线程的目的
FWIW:@Braj的回答说明了如何实现严格的交错。但是请注意,这实际上意味着一次只执行一个线程。此外,等待/通知将导致线程调度程序进行大量工作……有些情况下,应用程序的运行速度将比您刚刚执行的要慢得多在一根线上完成这项工作
在这个特定的例子中,有两个问题结合在一起,使得任何短期交错都不太可能:
在您的示例中,第一个线程可能会说“你好”在第二个线程准备好调度之前十次。请检查您的代码。粘贴精确的代码,这不会编译您的输出不必交错。它们可以。这是关于竞争条件的最好部分——不可预测的结果。我修复了代码,我的缺点几乎没有理由扩展
线程您应该实现一个Runnable
,并将其传递给线程的构造函数
@TheLostMind-有人可能会说OP的真正问题是试图从一开始就这样做。@StephenC-我不反对…:)。
public class Connor extends Thread {
private static Connor runner1 = new Connor();
private static Connor runner2 = new Connor();
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Hello " + i);
// wake up another thread to come out from wait state
if (runner1 == this) {
// wake up runner2
synchronized (runner2) {
runner2.notify();
}
} else {
// wake up runner1
synchronized (runner1) {
runner1.notify();
}
}
synchronized (this) {
try {
// say current thread to wait until notify by another thread
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
runner1.start();
runner2.start();
}
}
Hello 0
Hello 0
Hello 1
Hello 1
Hello 2
Hello 2
Hello 3
Hello 3
Hello 4
Hello 4
Hello 5
Hello 5
Hello 6
Hello 6
Hello 7
Hello 7
Hello 8
Hello 8
Hello 9
Hello 9