gpt4 book ai didi

java - 在Java中创建线程

转载 作者:行者123 更新时间:2023-12-01 09:18:11 25 4
gpt4 key购买 nike

我不明白,当我创建线程时,在第一种情况和第二种情况下我会得到什么?

总的来说,它们之间有区别吗?

ExecutorService executorService = Executors.newCachedThreadPool();

NewThread newThread = new NewThread(Thread.MAX_PRIORITY);
for(int i = 0;i < 5; i++){
executorService.execute(newThread);
}

ExecutorService executorService = Executors.newCachedThreadPool();

for(int i = 0;i < 5; i++){
NewThread newThread = new NewThread(Thread.MAX_PRIORITY);
executorService.execute(newThread);
}

最佳答案

根据您提供的内容,最佳答案是:在第一种情况下,您可能会收到错误。第二种方法是完全安全的(当然,假设您没有做不安全的事情)。

我知道,没有多大帮助,所以让我们了解一些背景知识。

NewThread 最有可能实现 Runnable,因此它应该有方法 void run(),如下所示:

class NewThread implements Runnable {
void run(){
//do something
}
}

现在,我们不知道实际的实现是什么,但我们仍然可以做一些分析。示例的整体结果取决于 NewThread 是有状态的还是无状态的。 “有状态”意味着该类的实例具有状态,例如一些内部字段(属性)。 “无状态”只是“无状态”。

如果 NewThread 是无状态的,那么在这两种情况下结果将是相同的 - ExecutorService 在新线程中执行 run() 方法,并且由于无论如何都没有变量的状态,所以我们不会有任何问题。

如果 NewThread 是有状态的,则第一个示例中可能会出现一些问题。编译器在这里不会有太大帮助,因为代码没问题,但逻辑可能会被破坏。想象一下:

class NewThread implements Runnable {
int x = 0;
void run(){
while (x<10)
x = x + 1;
}
}

您在这里看到的是竞争条件的手册示例。比我更好的作者比我更好地解释了这个问题,所以我只是提供一些阅读链接,例如 this , thisthis (当然,也可以使用谷歌)。基本上,这种情况下的竞争条件是,当我们执行 x = x + 1 时,我们首先需要读取 x,然后写入它。在读取和写入之间,其他线程可能修改了 x 的值,并且该值将被该线程覆盖。

有一种情况,NewThread 是有状态的,但仍然可以正常工作。如果您手动同步代码 - 使用synchronized关键字(例如,参见上面的第三个链接)或使用同步数据结构,就会发生这种情况:

class NewThread implements Runnable {
AtomicInteger x = new AtomicInteger(0);
void run(){
while (x<10)
x.incrementAndGet(); //getAndIncrement would work too - we don't care about the result, only about incrementing
}
}

“原子”意味着该类上的每个操作都被视为单步,例如读取或写入(而 x = x+1 是两步,这正是导致竞争条件的原因)。已经有几个可用的原子类 in JDK 。如果您想自己实现类似的东西,您可能会使用 synchronized keyword或一些lock-like object保护变量。

关于java - 在Java中创建线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40366954/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com