gpt4 book ai didi

java - 等到线程列表结束

转载 作者:行者123 更新时间:2023-11-29 07:45:09 26 4
gpt4 key购买 nike

我需要等到线程列表终止,但我的代码只有在 sleep 不是恒定的情况下才能工作我想知道为什么,这里是我的类测试:

如果我改变 Thread.sleep(200); ---> 线程.sleep(i*b);它工作正常!?

public class TestThread {
public static void main(String[] args) {
Object lock = new Object();
for ( int p=0; p<10; p++) {
final int i=p;
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("notify "+i);
synchronized(lock){
lock.notify();
}
}
}).start();
}
Integer counter=0;
synchronized (lock) {
try {
while(true){
System.out.println("Before wait");
if (counter==10)//wait until all threads ends
break;
lock.wait();
counter += 1;
System.out.println("After wait "+counter);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("End");
}
}

notifyAll() 的结果

Before wait
notify 3
notify 7
After wait 1
Before wait
notify 1
notify 2
notify 0
After wait 2
Before wait
notify 4
After wait 3
Before wait
After wait 4
Before wait
notify 5
After wait 5
Before wait
notify 6
notify 8
After wait 6
Before wait
notify 9
After wait 7
Before wait
After wait 8
Before wait

并且进程没有终止

最佳答案

这是发生了什么:

  1. 所有“worker”线程启动并 hibernate
  2. 锁由主线程通过synchronized(lock)获取
  3. 主线程通过调用lock.wait()释放锁并等待通知。
  4. 其中一个工作人员获取锁,调用通知并终止。
  5. 此时,它是纯随机的:主线程可以获取锁并增加计数器,或者其中一个工作线程可以获取锁并调用 notify

带注释的代码:

 public static void main(String[] args)
{
final Object lock = new Object();
for (int p = 0; p < 10; p++)
{
//You start each thread. They all go to sleep for 200ms.

final int i = p;
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
Thread.sleep(200);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("notify " + i);
synchronized (lock)
{
lock.notify();
}
}
}).start();
}
//At this point, all the thread are sleeping.



Integer counter = 0;
synchronized (lock)//The main thread acquire the lock, so even if the other thread wakes up, they will wait for the lock
{
try
{
while (true)
{
System.out.println("Before wait");
if (counter == 10)// wait until all threads ends
break;
lock.wait();// Object.wait() will release the lock on the object.
// So 1 of the thread will acquire the lock, call notify(), and release the lock.
// But you have no guarantee that the main thread will reacquire the lock right away !!
//its possible that all remaining waiting thread gets the lock and call notify(), before the main thread get
//a chance to continue. This is why, you may end up with a deadlock

counter += 1;

System.out.println("After wait");
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println("End");
}

这里有一个更好的方法来处理这个问题:

final List<Thread> workers = new ArrayList<Thread>();
for (int p = 0; p < 10; p++)
{
final int i = p;
final Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
try
{
Thread.sleep(200);//or do something a bit more useful
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
});
workers.add(t);
t.start();
}

for(Thread t : workers)
t.join();//wait until the thread finishes

关于java - 等到线程列表结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26509503/

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