java - 多线程同步

标签 java multithreading

同步与以下代码配合良好。

  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/

相关文章:

java - 如何标记文件并将数据输入到数组中?

java - 突然关闭应用程序而不进行任何 Activity ,抛出 IllegalStateException onMeasure()

java - sumGenerator(int 终止, int 增量)

java - 如何从线程中将项目添加到列表并保持添加顺序?

java - 有没有一种方法可以在不使用消息传递协议(protocol)的情况下从 Web 应用程序发送多个请求?

Java 启动画面无法在 Mac OSX 上运行,但可以在 PC 上运行

java - 在 SONAR 中进行方法覆盖时的小问题

C# 如何识别创建当前方法所在线程的方法?

java - 从线程启动一个 Activity

ios - AmazonS3Client putObject 仅适用于 iOS 主线程?