确定哪个线程获得了同步密钥

Determining which thread got the synchronized key

我正在学习如何使用线程,我 运行 在这个问题中,对于给定的代码,我需要说明某个线程是否能够访问某个函数。 这是代码:

public class InsideClass{}

public class SyncClass{
    private InsideClass in1;
    private InsideClass in2;

public SyncClass(InsideClass i, InsideClass i2){ in1 = i; in2 = i2; }

public synchronized void func1() { System.out.println("in func1"); }

public void func2() { synchronized(in1) { System.out.println("in func2"); }}

public static synchronized void func3() { System.out.println("in func3"); }

public void func4() { synchronized(in2) { System.out.println("in func4"); }}

public synchronized void func5() {
    synchronized(in1) {
        synchronized(in2){ System.out.println("in func5"); }}
}}

public class MyThread extends Thread{
    private SyncClass sc;

    public MyThread(SyncClass s) {
        sc = s;
    }

    public void run(){
        sc.func1();
        sc.func2();
        SyncClass.func3();
        sc.func4();
        sc.func5();
       }
    }

public class Sys {
    public static void main(String[] args) {
        InsideClass in1 = new InsideClass();
        InsideClass in2= new InsideClass();
        SyncClass s1 = new SyncClass(in1,in2);
        SyncClass s2 = new SyncClass(in2,in1);
        MyThread t1 = new MyThread(s1);
        MyThread t2 = new MyThread(s2);
        t1.start();
        t2.start();
    }
}

问题是这样的,假设t1正在执行task(i) (i=1,2,3,4),t2能执行func(i+1)还是会被阻塞?解释。 我写了完整的问题以防万一不清楚。

1) 假设 t1 正在执行 func1

2) 假设 t1 正在执行 func2。

3) 假设 t1 正在执行 func3

4) 假设 t1 正在执行 func4

5) func5 有一个独特的实现。

我不是在寻找所有这些问题的答案(尽管以防万一会很好),但我想得到一个对象的含义的解释(在这个例子中 in1/in2) 在同步块中,当使用这些对象 (s1,s2) 初始化 2 个其他对象时。如果 t1 正在执行同步的 func1,这对执行 func2 的尝试有何影响? (s1 和 s2 是用相同的对象初始化的事实如何影响这个问题)。

我希望我的问题足够清楚。谢谢!

现有代码无法编译。

func5 后跟三个左括号和三个右括号

没有右括号然后关闭class。

如果您有编译器,请重新编译代码并post。

一个synchronized语句获取给定对象的内在锁,然后执行它的主体,然后释放锁。

Object lock = new Object();
synchronized(lock) {
    ...body...
}

Java 运行时环境 (JRE) 永远不允许两个线程同时获取同一对象的内部锁。如果一个线程获得了锁,那么第二个尝试它的线程将被阻塞,直到第一个线程释放锁。

重要的是要知道无论线程如何退出...body...,锁都会被释放。不管它是 returns,还是 breaks,它是否简单地跑到最后,或者它是否抛出异常。无论如何都会释放锁。


有一种快捷方式可以编写整个主体都同步的成员函数。

这个:

class MyClass {
    synchronized void foobar(...args...) { ...body... }
}

意思和这个完全一样:

class MyClass {
    void foobar(...args...) {
        synchronized(this) { ...body... }
    }
}

synchronized static 函数也是如此,只是它在 class 对象上同步。

这个:

class MyClass {
    synchronized static void foobar(...args...) { ...body... }
}

意思和这个完全一样:

class MyClass {
    static void foobar(...args...) {
        synchronized(MyClass.class) { ...body... }
    }
}

记住变量和对象之间的区别很重要。如果变量 foo 在两个不同的上下文中引用两个不同的对象,则两个线程 可以 同时进入一个 synchronized(foo){...} 块。 (仔细考虑你的 in1in2 成员变量!)同样,如果两个线程在不同的对象上操作,则两个不同的线程可以同时调用同一个 synchronized 成员函数。 (您的示例有两个不同的 SyncClass 实例!)