java-se - java在线程同步块中修改同步对象会有什么后果?
大家讲道理
大家讲道理 2017-04-18 09:22:44
0
3
514

如果在线程同步块中将被同步对象修改会发生什么情况?

import java.util.concurrent.TimeUnit;

public class Main
{
public static void main(String[] args) {
    Object object = new Object() ;
    Syn syn1 = new Syn(object) ;
    Syn syn2 = new Syn(object) ;

    Thread thread = new Thread(syn1) ;
    thread.start() ;
    thread = new Thread(syn2) ;
    thread.start() ;
}
}

class Syn implements Runnable
{
private Object object ;

public Syn(Object object) {
    this.object = object;
}

@Override
public void run() {
    synchronized (object)
    {
        object = new Object() ;
        try {
            System.out.println("in sleep " + Thread.currentThread().getName());
            TimeUnit.SECONDS.sleep(1);
            System.out.println("out sleep" + Thread.currentThread().getName());
        }
        catch (Exception e)
        {
            System.err.println(e);
        }
    }
}
}

我用上面的程序测试发现在同步块中修改了object并不会影响两条线程的互斥, 那么为什么推荐使用不可变对象或者专用的锁来实现线程的互斥呢?

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

membalas semua(3)
洪涛

Lakukan ini:

synchronized (object) {
        object = new Object() ;
        //do something
}

Hasil yang diperoleh mungkin tidak konsisten dengan apa yang anda jangkakan. Kunci penyegerakan sebenarnya ialah kandungan yang ditunjukkan oleh rujukan objek. Apabila anda mengikat semula
rujukan objek kepada Objek baharu(), kandungan yang dikunci tidak akan berubah. Maksudnya, kandungan yang ditunjuk oleh objek di bahagian
syn2 masih dikunci, dan ia perlu menunggu sehingga blok penyegerakan dalam syn1 tamat sebelum ia boleh terus melaksanakan, jadi mereka (syn1, syn2)
dilaksanakan secara berurutan. Ini menyukarkan membaca dan mengekalkan kod.
Jadi Java mengesyorkan anda menggunakan final untuk mengubah suai objek yang memerlukan penyegerakan untuk memastikan ia tidak akan terikat semula dengan objek lain.

洪涛

Objek anda=new Object(); di sini tidak berguna Rujukan objek bagi objek semasa yang anda ubah di sini sememangnya boleh mencerminkan pengecualian bersama pada kali pertama utas melaksanakannya, tetapi ia tidak akan mencerminkannya pada kali kedua. dilaksanakan.
Anda boleh menulis ini sendiri:

while(true){
    synchronized(object){
        //todo
    }
}
小葫芦

Anda mengisytiharkan objek dalam Syn, yang menyebabkan setiap kejadian Syn memegang objek yang berbeza Jadi anda rasa terdapat masalah Penyelesaian yang saya gunakan adalah seperti berikut:

class Sync implements Runnable{
    private static Object object;
    //构造方法略
    @Override
    public void run(){
        synchronized(Object.class){
            //
        }
    }
}
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan