1. 程式人生 > 其它 >synchronized的鎖物件改變問題(轉)

synchronized的鎖物件改變問題(轉)

原文:https://www.jianshu.com/p/f6b3cc21f5d7

作者:跨界師

大家都知道synchronized是一個物件鎖,所以當物件變化時,鎖就會消失,就會沒有同步效果。

請看下面的問題:

package Thread;

/**
 * Created by zhangzheming on 2018/1/15.
 */

public class ChangeLock {

    private String lock = "lock";

    private void method(){
        synchronized (lock){
            try
{ System.out.println("當前執行緒:"+Thread.currentThread().getName()+"開始"); lock = "lock modify"; System.out.println("當前執行緒:"+Thread.currentThread().getName()+"完成"); }catch (Exception e){ e.printStackTrace(); } } }
public static void main(String[] args){ final ChangeLock locks = new ChangeLock(); Thread t1 = new Thread(new Runnable() { @Override public void run() { locks.method(); } }); Thread t2 = new Thread(new Runnable() { @Override
public void run() { locks.method(); } }); t1.start(); t2.start(); } }

結果是兩個執行緒是幾乎是同時完成任務,為什麼呢?
那是因為在進行method方法執行時,鎖物件改變了,這樣同步機制就消失,沒有了同步效果,這樣對於多執行緒操作時,便是每個執行緒物件都可以同時進行操作。

但是如果我們對class物件進行修改是否也會有上述情況呢?
答案是否定的。

package Thread;

/**
 * Created by zhangzheming on 2018/1/15.
 */

public class ModifyLock {

    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public synchronized void changeAttribute(String name,int age){
        try{
            System.out.println("當前執行緒:"+Thread.currentThread().getName()+"開始");
            this.setName(name);
            this.setAge(age);

            System.out.println("當前執行緒:"+Thread.currentThread().getName()+"修改物件內容為:"+this.getName()+","+this.getAge());
            Thread.sleep(2000);
            System.out.println("當前執行緒:"+Thread.currentThread().getName()+"結束");
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args){
        final ModifyLock locks = new ModifyLock();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                locks.changeAttribute("zhangsan",34);
            }
        },"t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                locks.changeAttribute("lisi",345);
            }
        },"t2");

        t1.start();
        t2.start();
    }
}

所以對於類物件的屬性進行修改,並不影響鎖的效果!