java多线程之-----静态同步synchronized方法与synchronized(class) 代码块
2017-10-29 15:10
816 查看
这个也是我在面试中被问到的一个题目(synchronize修饰静态方法和非静态方法的区别),这个没答出来
关键字synchronized还可以应用在static静态方法上,如果这样写,那是对当前的*.java文件对应的Class类进行持锁,测试项目:类文件Service.java代码如下:
ThreadA的代码:
ThreadB:
运行测试代码:
运行结果:
从运行结果来看,并没有什么特别地方,都是同步的效果,和将synchronized关键字加到非静态static方法上使用的效果是一样的,其实还是有本质上的不同,synchronized关键字加到static静态方法上是给Class类上锁,而synchronized关键字加到非static静态方法上是给对象上锁:
为了验证不是同一个锁。创建新的 项目,Service.java的代码如下:
ThreadA :
ThreadB:
ThreadC:
测试代码类:
运行结果:
结果产生异步的原因是持有不同的锁,一个是对象锁,一个是Class锁,而Class锁可以对类的所有对象实例起作用。如果不是Class锁的话,则多个实例就有多个锁,上文章有说到。下面验证Class锁对所有的实例起作用
修改运行测试文件如下:
运行结果:
由结果来看,依然是同步进行的,也就是说明了Class锁对所有实例起作用。
同步Synchronized(class) 的实质其实和synchronized static 方法一样,都是给Class加锁。验证:
修改Service代码:
结论:静态同步synchronized方法与synchronized(class)代码块效果一样,没有本质上的区别,与非静态的方法比起来,非静态的是给对象上锁。多个对象的时候会给多个对象上锁。依旧是异步的。而静态的方法,则因为持有的是Class锁,所以多个对象创建的时候,因为其Class依旧是一样的,所有就会是同步状态
关键字synchronized还可以应用在static静态方法上,如果这样写,那是对当前的*.java文件对应的Class类进行持锁,测试项目:类文件Service.java代码如下:
public class Service { synchronized public static void PrintA(){ try { System.out.println("线程的名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printA"); Thread.sleep(3000); System.out.println("线程的名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printA"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } synchronized public static void PrintB(){ System.out.println("线程的名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printB"); System.out.println("线程的名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printB"); } }
ThreadA的代码:
public class ThreadA extends Thread{ @Override public void 4000 run() { // TODO Auto-generated method stub super.run(); Service.PrintA(); } }
ThreadB:
public class ThreadB extends Thread{ @Override public void run() { // TODO Auto-generated method stub super.run(); Service.PrintB(); } }
运行测试代码:
public class Test1 { public static void main(String[] args) throws InterruptedException { ThreadA a = new ThreadA(); a.setName("A"); a.start(); ThreadB b = new ThreadB(); b.setName("B"); b.start(); } }
运行结果:
从运行结果来看,并没有什么特别地方,都是同步的效果,和将synchronized关键字加到非静态static方法上使用的效果是一样的,其实还是有本质上的不同,synchronized关键字加到static静态方法上是给Class类上锁,而synchronized关键字加到非static静态方法上是给对象上锁:
为了验证不是同一个锁。创建新的 项目,Service.java的代码如下:
public class Service { synchronized public static void PrintA() { try { System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printA"); Thread.sleep(3000); System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开printA"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } synchronized public static void PrintB() { System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printB"); System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开printB"); } synchronized public void PrintC() { System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printB"); System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开printB"); } }
ThreadA :
public class ThreadA extends Thread{ private Service service; public ThreadA(Service service) { // TODO Auto-generated constructor stub super(); this.service = service; } @Override public void run() { // TODO Auto-generated method stub super.run(); service.PrintA(); } }
ThreadB:
public class ThreadB extends Thread{ private Service service; public ThreadB(Service service) { // TODO Auto-generated constructor stub super(); this.service = service; } @Override public void run() { // TODO Auto-generated method stub super.run(); service.PrintB(); } }
ThreadC:
public class ThreadC extends Thread{ private Service service; public ThreadC(Service service) { // TODO Auto-generated constructor stub super(); this.service = service; } @Override public void run() { // TODO Auto-generated method stub super.run(); service.PrintC(); } }
测试代码类:
public class Test1 { public static void main(String[] args) throws InterruptedException { Service service = new Service(); ThreadA a = new ThreadA(service); a.setName("A"); a.start(); ThreadB b = new ThreadB(service); b.setName("B"); b.start(); ThreadC c = new ThreadC(service); c.setName("C"); c.start(); } }
运行结果:
结果产生异步的原因是持有不同的锁,一个是对象锁,一个是Class锁,而Class锁可以对类的所有对象实例起作用。如果不是Class锁的话,则多个实例就有多个锁,上文章有说到。下面验证Class锁对所有的实例起作用
修改运行测试文件如下:
public class Test1 { public static void main(String[] args) throws InterruptedException { Service service = new Service(); Service service2 = new Service(); ThreadA a = new ThreadA(service); a.setName("A"); a.start(); ThreadB b = new ThreadB(service2); b.setName("B"); b.start(); } }
运行结果:
由结果来看,依然是同步进行的,也就是说明了Class锁对所有实例起作用。
同步Synchronized(class) 的实质其实和synchronized static 方法一样,都是给Class加锁。验证:
修改Service代码:
public class Service { public void PrintA() { synchronized (Service.class) { try { System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printA"); Thread.sleep(3000); System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开printA"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void PrintB() { synchronized (Service.class) { System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "进入printB"); System.out.println("线程的名称为:" + Thread.currentThread().getName() + "在" + System.currentTimeMillis() + "离开printB"); } } }
注意:PrintA和PrintB方法加不加static都一样了这时 再次运行代码得:
结论:静态同步synchronized方法与synchronized(class)代码块效果一样,没有本质上的区别,与非静态的方法比起来,非静态的是给对象上锁。多个对象的时候会给多个对象上锁。依旧是异步的。而静态的方法,则因为持有的是Class锁,所以多个对象创建的时候,因为其Class依旧是一样的,所有就会是同步状态
相关文章推荐
- java 多线程10:synchronized锁机制 之 锁定类静态方法 和锁定类.Class 和 数据String的常量池特性 同步静态方法
- 深入理解Java中的同步静态方法和synchronized(class)代码块的类锁
- Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)
- java 多线程 方法1 继承Thread 加入同步synchronized代码块
- Java 多线程:synchronized 关键字 3ff0 用法(修饰类,方法,静态方法,代码块)
- java 多线程10:synchronized锁机制 之 锁定类静态方法 和锁定类.Class 和 数据String的常量池特性
- Java 多线程:synchronized 关键字用法(修饰类,方法,静态方法,代码块)
- java synchronized静态同步方法与非静态同步方法,同步语句块
- (转)初学Java多线程:使用Synchronized关键字同步类方法
- Java多线程 6 静态同步方法的锁
- 【JAVA】多线程之synchronized 同步数据 方法
- java synchronized静态同步方法与非静态同步方法,同步语句块
- JAVA 多线程静态同步函数的锁是class 对象
- java synchronized静态同步方法与非静态同步方法,同步语句块
- 初学Java多线程:使用Synchronized关键字同步类方法
- 从头认识多线程-2.17 同步方法与同步静态代码块持有的是不同的锁
- java synchronized静态同步方法与非静态同步方法,同步语句块
- 初学Java多线程:使用Synchronized关键字同步类方法
- java多线程-静态同步函数的锁是Class对象
- java synchronized修饰普通方法,修饰静态方法,修饰代码块,修饰线程run方法 比较