public class B {
public static String lock = "a";
public static void main(String[] args) {
MyThread t1 = new MyThread("Thread 1");
t1.start();
lock = "b";
MyThread t2 = new MyThread("Thread 2");
t2.start();
lock = "c";
MyThread t3 = new MyThread("Thread 3");
t3.start();
lock = "d";
MyThread t4 = new MyThread("Thread 4");
t4.start();
}
}
class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
@Override
public void run() {
synchronized (B.lock){
System.out.println(Thread.currentThread().getName() +" is going to sleep for 5 seconds");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " done sleeping ");
}
}
}
输出::
Thread 1 is going to sleep for 5 seconds
Thread 2 is going to sleep for 5 seconds
Thread 2 done sleeping
Thread 1 done sleeping
Thread 4 is going to sleep for 5 seconds
Thread 4 done sleeping
Thread 3 is going to sleep for 5 seconds
Thread 3 done sleeping
抱歉,问题不清楚。但我在这里的疑问是,由于我每次在线程启动后都更改锁定对象,为什么不是所有线程同时启动并锁定不同的字符串对象?我猜测可能是操作系统线程调度的原因。但每次执行都会导致仅同时启动 2 个线程(1 和 2),其余 2 个线程(3 和 4)等待获取锁。但为什么呢?
最佳答案
如果您想同时启动所有线程,则需要提供某种机制,使线程可以在开始工作之前知道其他线程已准备好执行。
类似于 java.util.concurrent.CountDownLatch
会对此有所帮助。基本思想是,您在线程中所做的第一件事就是等待 CountDownLatch;当所有线程都创建并启动时,您只需将闩锁计数到零。
例如,在您的 main
方法中:
CountDownLatch latch = new CountDownLatch(4);
MyThread t1 = new MyThread("Thread 1", latch);
t1.start();
//...
MyThread t4 = new MyThread("Thread 4", latch);
t4.start();
在您的MyThread
中:
class MyThread extends Thread{
private final CountDownLatch latch;
public MyThread(String name, CountDownLatch latch) {
super(name);
this.latch = latch;
}
@Override
public void run() {
latch.countDown();
latch.await();
synchronized (B.lock){
//...
}
}
}
线程现在将同时尝试进入同步
block 。然而,显然,任何时候只有其中一个会执行该 block 。
关于java - 为什么不是所有线程同时启动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31502954/