标签:main 应用 效果 except 代码块 public 开始 inter exce
synchronized(非this对象 x) 是将 x 对象本身作为“对象监视器”,因此有如下三个结论:
1)当多个线程同时执行 synchronized(x){}同步代码块时呈同步效果
2)当其他线程执行 x 对象中 synchronized 同步方法时呈同步效果
3)当其他线程执行 x 对象方法里的 synchronized(this) 代码块时也呈现同步效果。
关键字 synchronized 还可以应用在 static 静态方法上,如果这样写,则是对当前“类对象”进行持锁
注意区别:
synchronized 作用在非 static 方法上时,是“对象锁”,作用到 static 方法上时,是“Class锁”
示例:
public class SyncNotThis { public static void main(String[] args) { Service service = new Service(); Thread t1 = new Thread(() -> { Service.printA(); }); Thread t2 = new Thread(() -> { Service.printB(); }); Thread t3 = new Thread(() -> { service.printC(); }); t1.start(); t2.start(); t3.start(); } static class Service { /** * 静态方法 A */ synchronized public static void printA() { try { System.out.println("线程名称为:" + Thread.currentThread().getName() + "开始执行 A 方法"); Thread.sleep(1000); System.out.println("线程名称为:" + Thread.currentThread().getName() + "结束执行 A 方法"); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 静态方法B */ synchronized public static void printB() { try { System.out.println("线程名称为:" + Thread.currentThread().getName() + "开始执行 B 方法"); Thread.sleep(1000); System.out.println("线程名称为:" + Thread.currentThread().getName() + "结束执行 B 方法"); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 非静态方法C */ synchronized public void printC() { try { System.out.println("线程名称为:" + Thread.currentThread().getName() + "开始执行 C 方法"); Thread.sleep(500); System.out.println("线程名称为:" + Thread.currentThread().getName() + "结束执行 C 方法"); } catch (InterruptedException e) { e.printStackTrace(); } } } }
运行结果如图:
可以发现 方法 A、B的运行呈现同步效果,方法C与 A、B呈现异步效果,异步的原因是方法 C与 方法 A、B持有的是不同的锁
因为JVM中String常量池的存在,会导致 synchronized锁到同一对象
例:
public class SyncString { public static void main(String[] args) { Thread t1 = new Thread(() -> { String aa = "AA"; print(aa); }); Thread t2 = new Thread(() -> { String aa = "AA"; print(aa); }); t1.start(); t2.start(); } public static void print(String stringParam) { synchronized (stringParam) { try { System.out.println(Thread.currentThread().getName() + "begin"); Thread.sleep(2000); System.out.println(Thread.currentThread().getName() + "end"); } catch (InterruptedException e) { e.printStackTrace(); } } } }
运行结果如下:
因为String 常量池导致了锁的是同一 String 对象,所以两个线程是同步执行的
标签:main 应用 效果 except 代码块 public 开始 inter exce
原文地址:https://www.cnblogs.com/lkc9/p/12499134.html