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

时间:2017-06-17 16:17:03

标签: java multithreading synchronized

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

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正在执行任务(i)(i = 1,2,3,4),t2能够预先形成func(i + 1)还是会被阻塞?说明。 我写了完整的问题,以防它不清楚。

1)假设t1正在执行func1

  • a)t2能否预先形成func1?

  • b)t2能否预先形成func2?

  • c)t2能否预先形成func3?

  • d)t2能否预先形成func4?

2)假设t1正在执行func2。

  • a)t2能否预先形成func2?

  • b)t2能否预先形成func3?

  • c)t2能否预先形成func4?

3)假设t1正在执行func3

  • a)t2能否预先形成func3?

  • b)t2能否预先形成func4?

4)假设t1正在执行func4

  • a)t2能否预先形成func4?

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

  • a)这种方法有多少种不同的锁?指定他们是谁。

  • b)func5出现的问题是什么?你会如何解决这个问题?

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

我希望我的问题很清楚。谢谢!

2 个答案:

答案 0 :(得分:1)

synchronized语句获取给定对象的内在锁,然后执行其正文,然后发布

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

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

重要的是要知道无论线程如何退出...body...,锁都会被释放。它return是否为break,是否只是结束运行,还是抛出异常都无关紧要。无论如何都会释放锁。

这是一种编写整个身体同步的成员函数的快捷方式。

此:

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

与此完全相同:

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

synchronized static函数也是如此,除了它在类对象上同步。

此:

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

与此完全相同:

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

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

答案 1 :(得分:0)

代码不能编译。

func5后面有三个左括号和三个近括号

没有紧密的括号可以关闭课程。

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