JVM在序列中启动Threads的run()方法的适用性是什么?

时间:2015-06-26 17:52:36

标签: java multithreading synchronization

对于以下程序,ans是 - > print:printName,然后等待5秒然后打印:printValue

但据我所知,它由JVM挑选一个线程并启动其run方法。那么为什么它不能(printvalue printname然后5秒暂停)。

注意:我理解同步方法的概念,但我们如何确定JVM将始终选择线程t1作为其第一个线程。

class B {
    public synchronized void printName() {
        try {
            System.out.println("printName");
            Thread.sleep(5 * 1000);
        } catch (InterruptedException e) {
        }
    }

    public synchronized void printValue() {
        System.out.println("printValue");
    }
}

public class Test1 extends Thread {
    B b = new B();

    public static void main(String argv[]) throws Exception {
        Test1 t = new Test1();
        Thread t1 = new Thread(t, "t1");
        Thread t2 = new Thread(t, "t2");
        t1.start();
        t2.start();
    }

    public void run() {
        if (Thread.currentThread().getName().equals("t1")) {
            b.printName();
        } else {
            b.printValue();
        }
    }
}

2 个答案:

答案 0 :(得分:3)

在这种情况下,synchronize只是意味着它们不能同时运行,而不是它们必须按顺序运行。如果您希望它们按顺序运行,那么您不需要线程,或者您需要更复杂的排队机制。

所以,你是正确的,因为它可能是“printName”暂停“printValue”“printValue”“printName”暂停。

如果您多次运行该程序,您可能会更频繁地看到第一个。偶尔会看到第二个输出。偏差是因为线程1上的start()和线程2上的start()之间存在轻微延迟。

答案 1 :(得分:0)

  

我们如何确定JVM将始终选择线程t1作为其第一个线程。

您可以永远确保<div class="actions"> <%= f.submit "Log in" %> <%= f.hidden_field :cast_id, value: @cast.id %> </div> 线程在t1线程开始运行之前开始运行。如果你需要t1线程在t2线程做其他事情之前做某事,那么你将不得不使用一些同步对象(例如t2)来使Semaphore等待。

t2

但这并不是一种使用线程的智能方法。为什么不这样做呢?

Semaphore semaphore = new Semaphore(0);

Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
        doTheThingThatHasToBeDoneFirst();
        semaphore.release();
        doOtherStuff();
    }
}).start();

Thread t2 = new Thread(new Runnable() {
    @Override
    public void run() {
        semaphore.acquire();  //will not return until t1 thread calls release().
        doOtherOtherStuff();
    }
}).start();

根据经验,线程之间的同步越多,使用线程的好处就越少。如果您希望以某种顺序发生某些事情,您应该在一个线程中按顺序执行这些操作。

使用线程的技巧是设计你的程序,以便在重要的订单中有它可以做的有用的东西。