如果在线程同步块中将被同步对象修改会发生什么情况?
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并不会影响两条线程的互斥, 那么为什么推荐使用不可变对象或者专用的锁来实现线程的互斥呢?
Lakukan ini:
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:
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: