繁体   English   中英

循环中的Java-8线程

[英]Java-8 Thread in Loop

我创建这段代码:

static int i;

public static void main(String[] args) throws InterruptedException {

    for (i = 1; i <= 5; i++) {
        new Thread(() -> {
            hello(i);
        }).start();
    }

}

public static void hello(int i) {
    System.out.println("Thread number = " + i);
}

当您查看此内容时,您会认为它会打印:

Thread number = 1
Thread number = 2
Thread number = 3
Thread number = 4
Thread number = 5

但这是不正确的,它会打印一个随机int,并且它不打印逻辑6有时像这样:

Thread number = 5
Thread number = 6
Thread number = 6
Thread number = 6
Thread number = 6

我添加Thread.sleep(2000); 之后:

for (i = 1; i <= 5; i++) {
    new Thread(() -> {
        hello(i);
    }).start();
    Thread.sleep(2000);
}

它显示了一个正确的结果:

Thread number = 1
Thread number = 2
Thread number = 3
Thread number = 4
Thread number = 5

为什么在第一个结果中显示该结果,在第一个结果中显示6,而实际上却不存在6? 为什么不打印有序的1,2,3,...? 有什么解释吗?

Thread执行Runnable's run方法时,循环可能已经完成其执行,并且i最后一次取值为6 ,请记住您正在执行i<=5 ,这意味着循环完成时i将等于6

您得到的完全是逻辑输出,您可能会得到更多的奇数打印输出。 正如Thread中 start方法的javadoc所说:

结果是两个线程同时运行:当前线程(从调用返回到start方法)和另一个线程(执行其run方法)。

sub Thread在循环中开始执行的时间是不确定的,您得到的结果表明,在循环线程完成其最后一个循环之前执行了1个线程 ,在整个循环完成之后执行了4个其他线程。

添加Thread.sleep(2000);后获得预期订单的原因Thread.sleep(2000); 之所以如此,是因为您给了每个sub Thread足够的时间来执行实际操作,仅此而已。 执行顺序在本质上/理论上是不确定的。

如果像其他语言一样,您的线程代码是以不确定性的方式进行调度的,那么在运行线程代码时,将访问采用ACTUAL值的变量。

我重写了一些更简洁的代码:

公共班级主要{

static int i = 0;

public static void main(String[] args)  throws Exception
{
    // Lambda Runnable
    Runnable task = () -> {
        hello(i);
    };

    for (i = 1; i <= 5; i++) {
        new Thread(task).start();
    }

}

public static void hello(int i) {
    System.out.println("Thread number = " + i);
}

}

注意我必须将“ i”设置为静态。

一个更清洁的解决方案是使用带有“ i”的线程派生类并将其设置在构造函数中,因此子类的每个线程实例将具有自己的值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM