对于以下程序,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();
}
}
}
答案 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();
根据经验,线程之间的同步越多,使用线程的好处就越少。如果您希望以某种顺序发生某些事情,您应该在一个线程中按顺序执行这些操作。
使用线程的技巧是设计你的程序,以便在不重要的订单中有它可以做的有用的东西。