Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从同步块调用此同步方法可以吗?_Java_Multithreading_Asynchronous - Fatal编程技术网

Java 从同步块调用此同步方法可以吗?

Java 从同步块调用此同步方法可以吗?,java,multithreading,asynchronous,Java,Multithreading,Asynchronous,简单地说,我想知道这是否会改变行为。我假设是,因为调用someMethod()将锁定整个对象,而不仅仅是列表对象?但我对这种同步的东西还是比较陌生,所以我想得到一些更有教育意义的反馈 之前的: public void run() { int i = 0; while (!end) { synchronized (list) { while (list.size() == i) { try {

简单地说,我想知道这是否会改变行为。我假设是,因为调用someMethod()将锁定整个对象,而不仅仅是列表对象?但我对这种同步的东西还是比较陌生,所以我想得到一些更有教育意义的反馈

之前的:

public void run() {
    int i = 0;

    while (!end) {
        synchronized (list) {
            while (list.size() == i) {
                try {
                    list.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
之后:

public void run() {
    int i = 0;

    while (!end) {
        synchronized (list) {
            while (list.size() == i) {
                someMethod();
            }
        }
    }
}

public synchronized void someMethod() {
    try {
        list.wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

您是正确的-新代码具有不同的语义,因为
someMethod()
确实在其被调用的实例上进行了同步(因此,该同步与
列表上的同步完全无关)。但是,对
someMethod()
的调用将在按住
list
上的监视器时发生,因此对
run()
的调用相对于
list
而言是“同样线程安全的”

另一方面,您现在引入了多个线程同时直接调用
someMethod()
的可能性。由于对象本身的额外同步,您还引入了(可能是不必要的)与其他线程发生死锁的可能性。我建议改为:

public void someMethod() {
    synchronized (list) {
        try {
            list.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

此方法现在对于个人使用和通过
run()
调用都是安全的-请注意,在已同步的对象上同步是安全的;线程不会阻塞自身。

您是正确的-新代码具有不同的语义,因为
someMethod()
确实在其被调用的实例上进行了同步(因此,该同步与
列表上的同步完全无关)。但是,对
someMethod()
的调用将在按住
list
上的监视器时发生,因此对
run()
的调用相对于
list
而言是“同样线程安全的”

另一方面,您现在引入了多个线程同时直接调用
someMethod()
的可能性。由于对象本身的额外同步,您还引入了(可能是不必要的)与其他线程发生死锁的可能性。我建议改为:

public void someMethod() {
    synchronized (list) {
        try {
            list.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

此方法现在对于个人使用和通过
run()
调用都是安全的-请注意,在已同步的对象上同步是安全的;线程不会阻塞自身。

通过
同步
不会真正“锁定”对象。您只需确保对该特定对象进行同步的每个人的访问都通过锁进行“管理”

已同步的方法正在
上同步此

这意味着,如果您在某个对象的
列表上输入
syncronized
,您可以调用
syncronized
方法,一开始不会出现问题


需要考虑的一些事情:

此代码不会产生死锁:

public void foo() {
    synchronized (this) {
        someMethod();
    }
}

public synchronized void someMethod() {
    // ...
}
因为您已经在
上锁定了此
,但是:

public void foo() {
    synchronized (list) {
        someMethod();
    }
}

public synchronized void someMethod() {
    // ...
}

可能会与其他线程产生死锁!如果您在另一个
synchronized
节中输入
synchronized
节,您必须非常小心,因为
synchronized
不会真正“锁定”对象。您只需确保对该特定对象进行同步的每个人的访问都通过锁进行“管理”

已同步的方法正在
上同步此

这意味着,如果您在某个对象的
列表上输入
syncronized
,您可以调用
syncronized
方法,一开始不会出现问题


需要考虑的一些事情:

此代码不会产生死锁:

public void foo() {
    synchronized (this) {
        someMethod();
    }
}

public synchronized void someMethod() {
    // ...
}
因为您已经在
上锁定了此
,但是:

public void foo() {
    synchronized (list) {
        someMethod();
    }
}

public synchronized void someMethod() {
    // ...
}
可能会与其他线程产生死锁!如果在另一个
synchronized
节中输入
synchronized
节,您必须非常小心