实例方法上的synchronized
关键字可防止在同一个实例上调用该方法时同时调用该方法。
尝试以下(1):
class SynchTest {
public static void main(String[] args) {
// Note that we create a new Task each time.
new Thread(new Task()).start();
new Thread(new Task()).start();
new Thread(new Task()).start();
}
static class Task implements Runnable {
long start;
Task() {
this.start = System.currentTimeMillis();
}
@Override
public synchronized void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
System.out.println(System.currentTimeMillis() - start);
}
}
}
这将输出如下内容:
1000
1001
1001
换句话说,每个任务自创建以来经过的时间约为 1 秒,这意味着它们可以同时运行。
现在尝试以下(2):
class SynchTest {
public static void main(String[] args) {
// Now we pass the same instance each time.
Task t = new Task();
new Thread(t).start();
new Thread(t).start();
new Thread(t).start();
}
static class Task implements Runnable {
long start;
Task() {
this.start = System.currentTimeMillis();
}
@Override
public synchronized void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
System.out.println(System.currentTimeMillis() - start);
}
}
}
将同一个实例传递给所有 3 个线程意味着线程将尝试调用run
同一个实例。这会输出如下内容:
1001
2001
3001
换句话说,每个任务都等待前一个任务。
如果你真的想为每个对象synchronize
全部,你可以指定你自己的监控对象(3):run
class SynchTest {
public static void main(String[] args) {
new Thread(new Task()).start();
new Thread(new Task()).start();
new Thread(new Task()).start();
}
static class Task implements Runnable {
long start;
Task() {
this.start = System.currentTimeMillis();
}
static final Object STATIC_MONITOR = new Object();
@Override
public void run() {
synchronized (STATIC_MONITOR) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
System.out.println(System.currentTimeMillis() - start);
}
}
}
}
即使我们每次都创建一个新任务,它的输出也与示例 2 相同。
另请参阅:您是否应该同步运行方法?为什么或者为什么不?