java中的同步(这个)更安全?

java中的同步(这个)更安全?,java,synchronized,Java,Synchronized,我的一本教科书提到synchronized()的参数必须是。。。我知道这是错误的。但我听说既然同步(这个)更安全,就应该一直使用它。这是真的吗? 谢谢:)不,不一定总是这样。而且,静态方法的情况也不可能是这样,因为不存在这种情况 此外,有时认为与此同步是错误的,因为这样锁定对象在外部可见 public class Example { private final Object lock = new Object(); // does not compile, there is n

我的一本教科书提到synchronized()的参数必须是。。。我知道这是错误的。但我听说既然同步(这个)更安全,就应该一直使用它。这是真的吗?
谢谢:)

不,不一定总是这样。而且,静态方法的情况也不可能是这样,因为不存在这种情况

此外,有时认为与此同步是错误的,因为这样锁定对象在外部可见

public class Example {
    private final Object lock = new Object();

    // does not compile, there is no 'this' in static context.
    public static void staticMethod() {
        synchronized (this) {
        }
    }

    public void method() {
        int x = 3;
        //there is risk that someone else outside our code
        //uses same lock
        synchronized (this) {

        }
        //this lock is private
        synchronized (lock) {
        }
    }
}

不,不一定总是这样。而且,静态方法的情况也不可能是这样,因为不存在这种情况

此外,有时认为与此同步是错误的,因为这样锁定对象在外部可见

public class Example {
    private final Object lock = new Object();

    // does not compile, there is no 'this' in static context.
    public static void staticMethod() {
        synchronized (this) {
        }
    }

    public void method() {
        int x = 3;
        //there is risk that someone else outside our code
        //uses same lock
        synchronized (this) {

        }
        //this lock is private
        synchronized (lock) {
        }
    }
}

在我看来,如果你不确定在特定的地方同步(这)是否是个好主意,那么最好在字段和方法上使用“volatile”和“synchronized”

简单地说,volatile在变量上放置一个内部互斥体;synchronized在函数调用中放置一个内部互斥体;synchronized块在被参数锁定的代码段周围放置一个内部互斥体

通常你会对一个对象进行一次又一次的锁定,但有时你想锁定实例本身。。。尽管如此,如果您只需要访问整个类实例的一个成员/字段,我还是建议您在锁定整个类实例时要谨慎(您可以首先使用synchronized和volatile解决这个问题)


您可能希望(或不希望)锁定此项的真正原因是锁定的范围,如果锁定此项,您可以看到锁定。如果你初始化一个私有对象,锁就会被隐藏起来。

在我看来,如果你不确定在那个特定的地方同步(这)是否是个好主意,最好在字段和方法上使用“volatile”和“synchronized”

简单地说,volatile在变量上放置一个内部互斥体;synchronized在函数调用中放置一个内部互斥体;synchronized块在被参数锁定的代码段周围放置一个内部互斥体

通常你会对一个对象进行一次又一次的锁定,但有时你想锁定实例本身。。。尽管如此,如果您只需要访问整个类实例的一个成员/字段,我还是建议您在锁定整个类实例时要谨慎(您可以首先使用synchronized和volatile解决这个问题)


您可能希望(或不希望)锁定此项的真正原因是锁定的范围,如果锁定此项,您可以看到锁定。如果您初始化一个私有对象,锁就会隐藏起来。

synchronized的参数就是将保持放置在哪个对象上。这取决于您想在同步块中执行什么操作,它将决定参数应该是什么。使用
将保留当前对象


作为个人轶事,在我目前正在进行的项目中,我所有的同步保持都在COM端口上,因此发送和接收数据包之间没有冲突

同步的参数只是将保持放置在哪个对象上。这取决于您想在同步块中执行什么操作,它将决定参数应该是什么。使用
将保留当前对象


作为个人轶事,在我目前正在进行的项目中,我所有的同步保持都在COM端口上,因此发送和接收数据包之间不会发生冲突。使用哪个锁无关紧要。每个java.lang.Object都可以充当锁。您必须确保在相同可变状态下工作的所有操作都使用相同的锁

所以
synchronized(这个)

private final Object lock=new Object()

synchronized(lock)

使用哪个锁并不重要。每个java.lang.Object都可以充当锁。您必须确保在相同可变状态下工作的所有操作都使用相同的锁

所以
synchronized(这个)

private final Object lock=new Object()
已同步(锁定)

我的一本教科书提到synchronized()的参数必须是。。。我知道这是错误的

这是不正确的。不是课本不对,就是你误解了。Java语言允许您在任何(非空)对象引用上进行同步

但我听说既然同步(这个)更安全,就应该一直使用它。这是真的吗

不,那也不是真的。它并不安全,而且您当然不应该总是锁定此

 synchronized(obj1){
 -------
 }

 synchronized(obj2){
 -------
 }
事实上,如果您正在编写一个需要锁定“自身”的通用库类,通常最好声明一个私有锁字段;e、 g

    private final Object myLock = new Object();
。。。并锁定该对象,而不是锁定此对象。这就消除了当某些外部代码出于某种原因决定锁定库对象时可能出现的问题,从而导致不必要的争用,以及库类方法和外部代码之间可能出现的死锁


我怀疑这本教科书试图指出的一点是,所有使用原始锁在数据结构上实现互斥和同步的方法都必须使用正确的对象作为锁。这不一定是数据结构对象本身,但它确实需要表示该对象。。。从某种意义上说。(如果不锁定表示数据结构的对象,则在使用/更新数据结构时,有一个线程不排除其他线程的风险。)


下面是私有锁旨在避免的问题的示意图

/** This class implements thread-safe getting / setting by synchronizing on 'this' */
public class IntHolder {
    private int value;
    public int getValue() {
        synchronized(this) { return value; }
    }
    public void setValue(int value)
        synchronized(this) { this.value = value; }
}

/* Somewhere else, some other code (the "external code") used a holder instance
   as the lock for some larger-scale synchronization. */
IntHolder h = ...
synchronized (h) {
    /* Do something that takes a long time ... */
}
问题是,当外部代码将锁保持在
h
上时,其他线程将无法读取或更改保持器的值。如果这是有意的。。。那很好。但是,如果
IntHolder
类型的线程安全旨在“只是一个实现细节”,那么您现在可能会遇到一个潜在的意外故障
public synchronized void doThis() {


}
public void doThis() {
    synchronized (this) {

    }
}
public class MyClass {
    private final Object lock = new Object();   //Must be final

    public void doThis() {
        synchronized (lock) {

        }
    }
}