synchronized细节问题(二)

橙三吉。 提交于 2020-03-01 03:12:07

使用synchronized声明的方法在某些情况下是有弊端的,比如A线程调用同步的方法执行一个很长时间的任务,那么B线程就必须等待比较长的时间才能执行,这样的情况下,可以使用synchronized代码块去优化代码执行时间,也就是通常所说的减小锁的粒度。

synchronized可以使用任意的Object进行加锁,用法比较灵活。

另外特别注意一个问题,就是不要使用String的常量加锁,会出现死循环问题。

锁对象的改变问题,当使用一个对象进行加锁的时候,要注意对象本身发生改变的时候,那么持有的锁就不同。如果对象本身不发生改变,那么依然是同步的,即使是对象的属性发生了变化:

demo:

public class ModifyLock {    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    private int age;    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public synchronized void changeAttributte(String name, int age) {        System.out.println("当前线程 : " + Thread.currentThread().getName() + "开始");        this.setName(name);        this.setAge(age);        System.out.println("当前线程 : " + Thread.currentThread().getName() + "修改对象内容为:"                + this.getName() + "," + this.getAge());        try {            Thread.sleep(2000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("当前线程 : " + Thread.currentThread().getName() + "结束");    }    public static void main(String[] args) {        final ModifyLock modifyLock = new ModifyLock();        Thread t1 = new Thread(new Runnable() {            @Override            public void run() {                modifyLock.changeAttributte("张三",18);            }        },"t1");        Thread t2 = new Thread(new Runnable() {            @Override            public void run() {                modifyLock.changeAttributte("李四",21);            }        },"t2");        t1.start();        try {            Thread.sleep(100);        } catch (InterruptedException e) {            e.printStackTrace();        }        t2.start();    }}运行的结果:

当前线程 : t1开始
当前线程 : t1修改对象内容为:张三,18
当前线程 : t1结束
当前线程 : t2开始
当前线程 : t2修改对象内容为:李四,21
当前线程 : t2结束

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!