java - 为什么不是所有线程同时启动?

标签 java multithreading synchronization

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/

相关文章:

java - 如何在 Java Nashorn 中声明类?

c# - Java 相当于 C#'s "internal”

Java 到 C# 的转换,用于在 xamarin 中制作 androidstudio 应用程序

c++ - 如何让 std::thread 对传递给它的函数的参数进行一般构造?

c# - 帮助理解 C# 和多线程

java - 没有网络服务器的 Spring Cloud Starter Eureka

c# - 倒置后台 worker

java - Java 中内部锁定提供的内存可见性保证?

c# - 更新对不可变对象(immutable对象)的引用的首选方法是什么?

C# 和 C++ 进程间同步