同步与以下代码配合良好。
public class Main implements Runnable {
public static void main(String[] args) {
Main m = new Main();
for (int i = 0; i < 2; i++) {
Thread t = new Thread(m);
t.start();
}
}
@Override
public void run() {
synchronized(this) {
for (int i = 0; i < 500; i++) {
System.out.println(i);
}
}
}
}
// Synchronization isn't working here.
public class Main implements Runnable {
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
Thread t = new Thread(new Main());
t.start();
}
}
@Override
public void run() {
synchronized(this) {
for (int i = 0; i < 500; i++) {
System.out.println(i);
}
}
}
}
这个问题是在采访中被问到的。我对此有点困惑,所以我试图理解为什么同步不适用于第二个代码片段。谁能解释一下为什么同步不适用于第二个代码片段?
最佳答案
因为如果您正在处理单个对象,则会应用同步。
在第一种情况下,您有 Main 的单个可运行对象,即 m
在第二种情况下,您拥有 Main 的独立对象。
for(int i=0;i<2;i++){
Thread t = new Thread(new Main()); // independent objects for each thread
t.start();
}
<小时/>
说明:
如果您看到代码,您会在下面找到行
synchronized (this) {
this
指的是对象本身。所以锁是基于这个对象来应用的。因此,在多个主类对象的情况下,它们独立工作,就像在单个对象中同步仅应用于该对象一样。
欲了解更多信息,请参阅:Intrinsic Locks and Synchronization
文档中的代码
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) { // lock is acquired using lock1 object
c1++;
}
}
public void inc2() {
synchronized(lock2) { // lock is acquired using lock1 object
c2++;
}
}
}
在此示例中,您可以使用单个对象同时调用方法 inc1()
和 inc2()
,因为锁是在不同的对象上获取的。这将帮助您更好地理解它。
因此,在您的情况下,锁定是在 this
(对象本身)上获取的。因此,每当您有多个对象时,它将独立工作,而当您有单个对象时,它将同步工作。
关于java - 多线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31874690/