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();
    }
}

 

所以对于类对象的属性进行修改,并不影响锁的效果!

 
 
 
posted @ 2022-12-09 18:39  奋斗终生  Views(122)  Comments(0Edit  收藏  举报