使用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结束
来源:https://www.cnblogs.com/shmilyToHu/p/6386369.html