Java线程连接创建线程的顺序运行
当我运行下面的代码时,程序永远不会退出并卡在while循环中,这应该是预期的行为Java线程连接创建线程的顺序运行,java,multithreading,concurrency,Java,Multithreading,Concurrency,当我运行下面的代码时,程序永远不会退出并卡在while循环中,这应该是预期的行为 public class MyClass implements Runnable { public static final int NO_OF_THREADS = 100; private static int count; private static Set<Integer> set = new HashSet<>(); @Override pu
public class MyClass implements Runnable {
public static final int NO_OF_THREADS = 100;
private static int count;
private static Set<Integer> set = new HashSet<>();
@Override
public void run() {
for(int i=0 ;i<10000; i++) {
set.add(count++);
}
}
public static void main(String[] args) throws Exception {
Thread[] threadArray = new Thread[NO_OF_THREADS];
for(int i=0; i<NO_OF_THREADS; i++) {
threadArray[i] = new Thread(new MyClass());
}
for(int i=0; i<NO_OF_THREADS; i++) {
threadArray[i].start();
//threadArray[i].join();
}
while(set.size()!=1000000) {}
}
}
公共类MyClass实现可运行{
公共静态final int NO_OF_线程=100;
私有静态整数计数;
私有静态集=新HashSet();
@凌驾
公开募捐{
对于(int i=0;i是这是预期的行为,当您的连接被注释时,多个线程将在同一时间访问您的集合,您将有竞争条件,在这种情况下,多个线程的计数将相同,因此基本上您将在同一位置添加多个元素,因此您将不会有预期的i数tems在集合中,因此循环条件将始终为真,并且您的应用程序不会退出
如果您的联接没有注释,则主线程将被阻塞,直到每个线程完成为止。当第一个线程启动并且主线程移动到联接时,主线程将被阻塞,并等待第一个线程完成,然后再移动到循环的下一个迭代,因此您将无法同时访问“count”因此,所有添加的元素都将是不同的,在注释时称为竞态条件,而在未注释时称为竞态条件。这就是问题所在。未注释时没有竞态,因为连接
强制主线程在启动新线程之前等待线程完成。因此一次只能有一个线程。@litite,我真傻,竟然把连接放在循环中。谢谢!@azuri,如果我是老师,我会教我的学生使用Executors。newFixedThreadPool(n)
在教他们使用线程之前
。我的问题不是关于第一种情况,即我同意争用条件是重复计数值的原因。我的问题是,当我取消对join()的注释时,为什么在第二种情况下没有争用条件@azuri i为其添加了一个解释,请检查它。HashSet
的当前变异也会导致许多问题。有关@azuri的详细信息,请参阅此问题