3

我正在学习 java 线程(同步和锁),但不知何故我无法找到这两件事之间的区别。

// Two different instances of SyncExample
Thread a1 = new Thread(new SyncExample(), "A");
Thread b1 = new Thread(new SyncExample(), "B");

// Same instance is passed to both the threads
SyncExample syn = new SyncExample();
Thread a2 = new Thread(syn, "A");
Thread b2 = new Thread(syn, "B");

// I believe in total 4 stacks are built.
a1.start();
b1.start();

a2.start();
b2.start();

public class SyncExample implements Runnable {

    Object obj = new Object();

    @Override
    public void run() {

        this.myName();
    }

    private void myName() {

        synchronized (obj) {
            System.out.print("Define" + Thread.currentThread().getName());
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                System.out.println(ex);
            }
            System.out.print("tly" + Thread.currentThread().getName());
        }
        System.out.println(" Maybe" + Thread.currentThread().getName());
    }
}


public class SyncExample implements Runnable {

    Object obj = new Object();

    @Override
    public void run() {

        this.myName();
    }

    private void myName() {

        synchronized (obj) {
            System.out.print("Define" + Thread.currentThread().getName());
            try {
                Thread.sleep(500);
            } catch (InterruptedException ex) {
                System.out.println(ex);
            }
            System.out.print("tly" + Thread.currentThread().getName());
        }
        System.out.println(" Maybe" + Thread.currentThread().getName());
    }
}

但这里的问题是当我使用

1 - 相同的参考输出是:

DefineAtlyA MaybeA
DefineBtlyB MaybeB

2 - 2 个不同的实例:

DefineADefineBtlyAtlyB MaybeB
 MaybeA

谁能解释一下当我们将可运行目标传递给线程类 1. 相同实例 2. 不同实例时有什么不同

4

2 回答 2

2

在您的代码中,当您传递两个不同的实例(SyncExample类)时,每个实例都有自己的锁对象(由变量持有obj)。由于有两个不同的锁对象,每个线程获取一个锁并并行执行,导致线程 A 和 B ( DefineADefineBtlyAtlyB MaybeB MaybeA) 的交错输出。

而当你传递同一个实例时,只有一个SyncExample类实例。结果,只有一个锁对象实例(由变量持有obj)。因此这个锁对象将在两个线程之间共享。由于这种共享,只有一个线程(比如 T1)能够进入同步块;另一个线程(比如 T2)会等到 T1 存在同步块。因此,在您的执行中,您首先会看到线程 A 的所有打印语句,然后是线程 B ( DefineAtlyA MaybeA DefineBtlyB MaybeB) 的所有语句。

如果我概括一下:当您传递不同的实例时,只有静态变量会影响线程的并行执行,但是当您传递单个实例时,静态和类级别的变量(例如obj代码中的变量)都会影响线程的并行执行。

于 2013-03-04T07:36:42.600 回答
1

输出应该提示您不同之处。

当您将相同的内容传递SyncExample给两个不同的线程时,其中只有一个能够获得锁定并在块obj中执行代码。synchronized

当您传入两个不同SyncExample的对象时,两个线程都能够同时执行,因为它们在不同的对象上同步。

于 2013-03-04T06:27:22.137 回答