简体   繁体   English

实例的同步方法可以被同步语句锁定吗

[英]Can a synchronized method of an instance be locked by synchronized statement

I have run into a code piece in official tutorial of concurrency : 我在并发的官方教程中遇到了一段代码:

public SynchronizedRGB(int red,
                           int green,
                           int blue,
                           String name) {
        check(red, green, blue);
        this.red = red;
        this.green = green;
        this.blue = blue;
        this.name = name;
    }

    public void set(int red,
                    int green,
                    int blue,
                    String name) {
        check(red, green, blue);
        synchronized (this) {
            this.red = red;
            this.green = green;
            this.blue = blue;
            this.name = name;
        }
    }

    public synchronized int getRGB() {
        return ((red << 16) | (green << 8) | blue);
    }

    public synchronized String getName() {
        return name;
    }

    public synchronized void invert() {
        red = 255 - red;
        green = 255 - green;
        blue = 255 - blue;
        name = "Inverse of " + name;
    }
}

My question is : 我的问题是:

If a thread uses set method, can another thread use one of the synchronized methods, or the other way around ? 如果一个线程使用set方法,另一个线程可以使用其中一个同步方法,还是相反?

No, they can't. 不,他们不能。 At least not while you are inside the synchronized(this) block. 至少当您位于synchronized(this)块中时,才不会。 Declaring a non-static method as synchronized has the same effect as putting everything inside the method into a synchronized(this) {} block. 将非静态方法声明为已synchronized具有与将方法中的所有内容都放入synchronized(this) {}块相同的效果。

Thus, while one thread is inside a non-static method declared as synchronized , no other thread may execute either a synchronized method or a synchronized(this) {} block. 因此,当一个线程位于声明为synchronized的非静态方法内部时,其他任何线程都不能执行synchronized方法或synchronized(this) {}块。

For methods declared as static in the class ThisClass : They are handled the same way as if the contents of the method was inside a synchronized(ThisClass.class) {} block. 对于在类ThisClass声明为static方法:对其处理方式与该方法的内容在synchronized(ThisClass.class) {}块内一样。


For your example, if you wonder why this does not work correctly: 对于您的示例,如果您想知道为什么这不能正常工作:

SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
int myColorInt = color.getRGB();      //Statement 1
String myColorName = color.getName(); //Statement 2

getRGB() and getName() do lock on this . getRGB()getName()确实this进行了锁定。 But between the two method calls the lock is released again so that another thread could acquire it, then release it, and only then the first thread could finally execute getName() . 但是在这两个方法调用之间,再次释放了锁,以便另一个线程可以获取该锁,然后释放它,只有第一个线程才可以最终执行getName() Thus another thread could change the color between the the RGB and the Name getter so the name and RGB returned would not fit to the same color. 因此,另一个线程可以更改RGBName getter之间的颜色,因此返回的name和RGB将不适合同一颜色。

If you do it like this: 如果您这样做:

SynchronizedRGB color = new SynchronizedRGB(0, 0, 0, "Pitch Black");
...
synchronized(color) {
    int myColorInt = color.getRGB();      //Statement 1
    String myColorName = color.getName(); //Statement 2
}

In this case the lock on the object is not released between getRGB() and getName() so that no thread could acquire it at this time. 在这种情况下,对象的锁定不会在getRGB()getName()之间释放,因此此时没有线程可以获取它。

No; 没有; synchronized methods will synchronize on this . synchronized方法将this同步。

Also, this is poor code; 而且,这是糟糕的代码; the entire class should be immutable, solving all threading problems without synchronization. 整个类应该是不可变的,无需同步即可解决所有线程问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM