两个线程同时执行同步块
Two threads executing synchronized block simultaneously
下面是 Thread
进入同步块,等待 5 秒然后退出的代码。我同时启动了两个 Thread
个实例。
预期其中一个线程将拥有同步对象上的锁,而另一个将等待。 5秒后,当锁拥有者退出时,等待线程就会执行。
但是,实际上,两个线程都在同时执行同步块,同时退出。
Expected Output:
Thread-X <timeX> received the lock.
Thread-X <timeX+5s> exiting...
Thread-Y <timeY> received the lock.
Thread-Y <timeY+5s> exiting...
Actual Output:
Thread-X <time> received the lock.
Thread-Y <time> received the lock.
Thread-X <time+5s> exiting...
Thread-Y <time+5s> exiting...
我是不是漏掉了什么?
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test2 {
public static void main(String[] args) {
MyRunnable m = new MyRunnable();
Thread t = new Thread(m);
Thread t1 = new Thread(m);
t.start();
t1.start();
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
synchronized (this) {
try {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " received the lock.");
wait(5000);
date = new Date(System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " exiting...");
} catch(InterruptedException ie) {}
}
}
}
答案在 java.lang.Object.wait(long) 中,其文档说:
[...] This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. [...]
使用
Thread.sleep(5000);
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
以下来自 Oracle Tutorials 的引述解释了这种情况:
When wait
is invoked, the thread releases the lock and suspends
execution.
此外,只有一个线程可以执行由同一对象保护的 synchronized
块!在您的示例中调用 wait
会释放锁,从而允许另一个线程获取锁。
下面是 Thread
进入同步块,等待 5 秒然后退出的代码。我同时启动了两个 Thread
个实例。
预期其中一个线程将拥有同步对象上的锁,而另一个将等待。 5秒后,当锁拥有者退出时,等待线程就会执行。
但是,实际上,两个线程都在同时执行同步块,同时退出。
Expected Output:
Thread-X <timeX> received the lock.
Thread-X <timeX+5s> exiting...
Thread-Y <timeY> received the lock.
Thread-Y <timeY+5s> exiting...
Actual Output:
Thread-X <time> received the lock.
Thread-Y <time> received the lock.
Thread-X <time+5s> exiting...
Thread-Y <time+5s> exiting...
我是不是漏掉了什么?
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test2 {
public static void main(String[] args) {
MyRunnable m = new MyRunnable();
Thread t = new Thread(m);
Thread t1 = new Thread(m);
t.start();
t1.start();
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
synchronized (this) {
try {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " received the lock.");
wait(5000);
date = new Date(System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " exiting...");
} catch(InterruptedException ie) {}
}
}
}
答案在 java.lang.Object.wait(long) 中,其文档说:
[...] This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. [...]
使用
Thread.sleep(5000);
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
以下来自 Oracle Tutorials 的引述解释了这种情况:
When
wait
is invoked, the thread releases the lock and suspends execution.
此外,只有一个线程可以执行由同一对象保护的 synchronized
块!在您的示例中调用 wait
会释放锁,从而允许另一个线程获取锁。