synchronized(this)、synchronized(class)与synchronized(Object)的区别
在多线程开发中,我们经常看到synchronized(this)、synchronized(*.class)与synchronized(任意对象)这几种类型同步方法。但是是否知道这几种写法有什么区别了?下面根据代码来分析:
synchronized代码块间的同步性
- package com.zwz.thread.demo1;
- public class ObjectService {
- public void serviceMethodA(){
- try {
- synchronized (this) {
- System.out.println("A begin time="+System.currentTimeMillis());
- Thread.sleep(2000);
- System.out.println("A end time="+System.currentTimeMillis());
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- public void serviceMethodB(){
- synchronized (this) {
- System.out.println("B begin time="+System.currentTimeMillis());
- System.out.println("B end time="+System.currentTimeMillis());
- }
- }
- }
package com.zwz.thread.demo1;public class ObjectService {public void serviceMethodA(){try {synchronized (this) {System.out.println("A begin time="+System.currentTimeMillis());Thread.sleep(2000);System.out.println("A end time="+System.currentTimeMillis());}} catch (InterruptedException e) {e.printStackTrace();}}public void serviceMethodB(){synchronized (this) {System.out.println("B begin time="+System.currentTimeMillis());System.out.println("B end time="+System.currentTimeMillis());}}
}
- package com.zwz.thread.demo1;
- public class ThreadA extends Thread {
- private ObjectService objectService;
- public ThreadA(ObjectService objectService){
- super();
- this.objectService=objectService;
- }
- @Override
- public void run() {
- super.run();
- objectService.serviceMethodA();
- }
- }
package com.zwz.thread.demo1;public class ThreadA extends Thread {private ObjectService objectService;public ThreadA(ObjectService objectService){super();this.objectService=objectService;}@Overridepublic void run() {super.run();objectService.serviceMethodA();}
}
- package com.zwz.thread.demo1;
- public class ThreadB extends Thread {
- private ObjectService objectService;
- public ThreadB(ObjectService objectService){
- super();
- this.objectService=objectService;
- }
- @Override
- public void run() {
- super.run();
- objectService.serviceMethodB();
- }
- }
package com.zwz.thread.demo1;public class ThreadB extends Thread {private ObjectService objectService;public ThreadB(ObjectService objectService){super();this.objectService=objectService;}@Overridepublic void run() {super.run();objectService.serviceMethodB();}
}
- package com.zwz.thread.demo1;
- public class MainTest {
- public static void main(String[] args) {
- ObjectService service=new ObjectService();
- ThreadA a=new ThreadA(service);
- a.setName("a");
- a.start();
- ThreadB b=new ThreadB(service);
- b.setName("b");
- b.start();
- }
- }
package com.zwz.thread.demo1;public class MainTest {public static void main(String[] args) {ObjectService service=new ObjectService();ThreadA a=new ThreadA(service);a.setName("a");a.start();ThreadB b=new ThreadB(service);b.setName("b");b.start();}
}
运行结果:
结论:
当一个线程访问ObjectService的一个synchronized (this)同步代码块时,其它线程对同一个ObjectService中其它的synchronized (this)同步代码块的访问将是堵塞,这说明synchronized (this)使用的对象监视器是一个。
验证synchronized (this)代码块是锁定当前对象
- package com.zwz.thread.demo2;
- public class ObjectService {
- public void objectMethodA(){
- System.out.println("run----objectMethodA");
- }
- public void objectMethodB(){
- synchronized (this) {
- try {
- for (int i = 1; i <= 10; i++) {
- System.out.println("synchronized thread name:"+Thread.currentThread().getName()+"-->i="+i);
- Thread.sleep(1000);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
package com.zwz.thread.demo2;public class ObjectService {public void objectMethodA(){System.out.println("run----objectMethodA");}public void objectMethodB(){synchronized (this) {try {for (int i = 1; i <= 10; i++) {System.out.println("synchronized thread name:"+Thread.currentThread().getName()+"-->i="+i);Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}}}
}
- package com.zwz.thread.demo2;
- public class ThreadA extends Thread {
- private ObjectService objectService;
- public ThreadA(ObjectService objectService) {
- super();
- this.objectService = objectService;
- }
- @Override
- public void run() {
- super.run();
- objectService.objectMethodA();
- }
- }
package com.zwz.thread.demo2;public class ThreadA extends Thread {private ObjectService objectService;public ThreadA(ObjectService objectService) {super();this.objectService = objectService;}@Overridepublic void run() {super.run();objectService.objectMethodA();}
}
- package com.zwz.thread.demo2;
- public class ThreadB extends Thread {
- private ObjectService objectService;
- public ThreadB(ObjectService objectService) {
- super();
- this.objectService = objectService;
- }
- @Override
- public void run() {
- super.run();
- objectService.objectMethodB();
- }
- }
package com.zwz.thread.demo2;public class ThreadB extends Thread {private ObjectService objectService;public ThreadB(ObjectService objectService) {super();this.objectService = objectService;}@Overridepublic void run() {super.run();objectService.objectMethodB();}
}
- package com.zwz.thread.demo2;
- public class MainTest {
- public static void main(String[] args) throws InterruptedException {
- ObjectService service=new ObjectService();
- ThreadB b=new ThreadB(service);
- b.start();
- Thread.sleep(2000);
- ThreadA a=new ThreadA(service);
- a.start();
- }
- }
package com.zwz.thread.demo2;public class MainTest {public static void main(String[] args) throws InterruptedException {ObjectService service=new ObjectService();ThreadB b=new ThreadB(service);b.start();Thread.sleep(2000);ThreadA a=new ThreadA(service);a.start();}
}
运行结果:
可以看到objectMethodA方法异步执行了,下面我们将objectMethodA()加上同步。
- package com.zwz.thread.demo2;
- public class ObjectService {
- public synchronized void objectMethodA(){
- System.out.println("run----objectMethodA");
- }
- public void objectMethodB(){
- synchronized (this) {
- try {
- for (int i = 1; i <= 10; i++) {
- System.out.println("synchronized thread name:"+Thread.currentThread().getName()+"-->i="+i);
- Thread.sleep(1000);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
package com.zwz.thread.demo2;public class ObjectService {public synchronized void objectMethodA(){System.out.println("run----objectMethodA");}public void objectMethodB(){synchronized (this) {try {for (int i = 1; i <= 10; i++) {System.out.println("synchronized thread name:"+Thread.currentThread().getName()+"-->i="+i);Thread.sleep(1000);}} catch (InterruptedException e) {e.printStackTrace();}}}
}
运行结果:
结论:
上面三个小例子我们可以知道,多个线程调用同一个对象中的不同名称的synchronized同步方法或synchronized(this)同步代码块时,是同步的。
1、synchronized同步方法
①对其它的synchronized同步方法或synchronized(this)同步代码块调用是堵塞状态;
②同一时间只有一个线程执行synchronized同步方法中的代码。
2、synchronized(this)同步代码块
①对其它的synchronized同步方法或synchronized(this)同步代码块调用是堵塞状态;
②同一时间只有一个线程执行synchronized同步方法中的代码。
将任意对象作为对象监视器
- package com.zwz.thread.demo3;
- public class ObjectService {
- private String uname;
- private String pwd;
- String lock=new String();
- public void setUserNamePassWord(String userName,String passWord){
- try {
- synchronized (lock) {
- System.out.println("thread name="+Thread.currentThread().getName()
- +" 进入代码快:"+System.currentTimeMillis());
- uname=userName;
- Thread.sleep(3000);
- pwd=passWord;
- System.out.println("thread name="+Thread.currentThread().getName()
- +" 进入代码快:"+System.currentTimeMillis()+"入参uname:"+uname+"入参pwd:"+pwd);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
package com.zwz.thread.demo3;public class ObjectService {private String uname;private String pwd;String lock=new String();public void setUserNamePassWord(String userName,String passWord){try {synchronized (lock) {System.out.println("thread name="+Thread.currentThread().getName()+" 进入代码快:"+System.currentTimeMillis());uname=userName;Thread.sleep(3000);pwd=passWord;System.out.println("thread name="+Thread.currentThread().getName()+" 进入代码快:"+System.currentTimeMillis()+"入参uname:"+uname+"入参pwd:"+pwd);}} catch (InterruptedException e) {e.printStackTrace();}}
}
- package com.zwz.thread.demo3;
- public class ThreadA extends Thread {
- private ObjectService objectService;
- public ThreadA(ObjectService objectService) {
- super();
- this.objectService = objectService;
- }
- @Override
- public void run() {
- objectService.setUserNamePassWord("a", "aa");
- }
- }
package com.zwz.thread.demo3;public class ThreadA extends Thread {private ObjectService objectService;public ThreadA(ObjectService objectService) {super();this.objectService = objectService;}@Overridepublic void run() {objectService.setUserNamePassWord("a", "aa");}
}
- package com.zwz.thread.demo3;
- public class ThreadB extends Thread {
- private ObjectService objectService;
- public ThreadB(ObjectService objectService) {
- super();
- this.objectService = objectService;
- }
- @Override
- public void run() {
- objectService.setUserNamePassWord("b", "bb");
- }
- }
package com.zwz.thread.demo3;public class ThreadB extends Thread {private ObjectService objectService;public ThreadB(ObjectService objectService) {super();this.objectService = objectService;}@Overridepublic void run() {objectService.setUserNamePassWord("b", "bb");}
}
- package com.zwz.thread.demo3;
- public class MainTest {
- public static void main(String[] args) {
- ObjectService service=new ObjectService();
- ThreadA a=new ThreadA(service);
- a.setName("A");
- a.start();
- ThreadB b=new ThreadB(service);
- b.setName("B");
- b.start();
- }
- }
package com.zwz.thread.demo3;public class MainTest {public static void main(String[] args) {ObjectService service=new ObjectService();ThreadA a=new ThreadA(service);a.setName("A");a.start();ThreadB b=new ThreadB(service);b.setName("B");b.start();}
}
运行结果:
下面我把String lock=new String();放在方法中会有啥结果了:
- package com.zwz.thread.demo3;
- public class ObjectService {
- private String uname;
- private String pwd;
- public void setUserNamePassWord(String userName,String passWord){
- try {
- String lock=new String();
- synchronized (lock) {
- System.out.println("thread name="+Thread.currentThread().getName()
- +" 进入代码快:"+System.currentTimeMillis());
- uname=userName;
- Thread.sleep(3000);
- pwd=passWord;
- System.out.println("thread name="+Thread.currentThread().getName()
- +" 进入代码快:"+System.currentTimeMillis()+"入参uname:"+uname+"入参pwd:"+pwd);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
package com.zwz.thread.demo3;public class ObjectService {private String uname;private String pwd;public void setUserNamePassWord(String userName,String passWord){try {String lock=new String();synchronized (lock) {System.out.println("thread name="+Thread.currentThread().getName()+" 进入代码快:"+System.currentTimeMillis());uname=userName;Thread.sleep(3000);pwd=passWord;System.out.println("thread name="+Thread.currentThread().getName()+" 进入代码快:"+System.currentTimeMillis()+"入参uname:"+uname+"入参pwd:"+pwd);}} catch (InterruptedException e) {e.printStackTrace();}}
}
运行结果:
结论:
多个线程持有对象监视器作为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(任意自定义对象)同步代码快。
synchronized(任意自定义对象)与synchronized同步方法共用
- package com.zwz.thread.demo4;
- public class ObjectService {
- private String lock=new String();
- public void methodA(){
- try {
- synchronized (lock) {
- System.out.println("a begin");
- Thread.sleep(3000);
- System.out.println("a end");
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- public synchronized void methodB(){
- System.out.println("b begin");
- System.out.println("b end");
- }
- }
package com.zwz.thread.demo4;public class ObjectService {private String lock=new String();public void methodA(){try {synchronized (lock) {System.out.println("a begin");Thread.sleep(3000);System.out.println("a end");}} catch (InterruptedException e) {e.printStackTrace();}}public synchronized void methodB(){System.out.println("b begin");System.out.println("b end");}
}
- package com.zwz.thread.demo4;
- public class ThreadA extends Thread {
- private ObjectService objectService;
- public ThreadA(ObjectService objectService) {
- super();
- this.objectService = objectService;
- }
- @Override
- public void run() {
- objectService.methodA();
- }
- }
package com.zwz.thread.demo4;public class ThreadA extends Thread {private ObjectService objectService;public ThreadA(ObjectService objectService) {super();this.objectService = objectService;}@Overridepublic void run() {objectService.methodA();}
}
- package com.zwz.thread.demo4;
- public class ThreadB extends Thread {
- private ObjectService objectService;
- public ThreadB(ObjectService objectService) {
- super();
- this.objectService = objectService;
- }
- @Override
- public void run() {
- objectService.methodB();
- }
- }
package com.zwz.thread.demo4;public class ThreadB extends Thread {private ObjectService objectService;public ThreadB(ObjectService objectService) {super();this.objectService = objectService;}@Overridepublic void run() {objectService.methodB();}
}
- package com.zwz.thread.demo4;
- public class MainTest {
- public static void main(String[] args) {
- ObjectService service=new ObjectService();
- ThreadA a=new ThreadA(service);
- a.setName("A");
- a.start();
- ThreadB b=new ThreadB(service);
- b.setName("B");
- b.start();
- }
- }
package com.zwz.thread.demo4;public class MainTest {public static void main(String[] args) {ObjectService service=new ObjectService();ThreadA a=new ThreadA(service);a.setName("A");a.start();ThreadB b=new ThreadB(service);b.setName("B");b.start();}}
运行结果:
结论:
使用synchronized(任意自定义对象)进行同步操作,对象监视器必须是同一个对象。不过不是同一个,运行就是异步执行了。
静态同步synchronized方法与synchronized(*.class)代码块
静态同步synchronized方法
- package com.zwz.thread.demo6;
- public class ObjectService {
- public synchronized static void methodA(){
- try {
- System.out.println("static methodA begin 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());
- Thread.sleep(3000);
- System.out.println("static methodA end 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- public synchronized static void methodB(){
- System.out.println("static methodB begin 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());
- System.out.println("static methodB end 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());
- }
- }
package com.zwz.thread.demo6;public class ObjectService {public synchronized static void methodA(){try {System.out.println("static methodA begin 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());Thread.sleep(3000);System.out.println("static methodA end 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());} catch (InterruptedException e) {e.printStackTrace();}}public synchronized static void methodB(){System.out.println("static methodB begin 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());System.out.println("static methodB end 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());}
}
- package com.zwz.thread.demo6;
- public class ThreadA extends Thread {
- @Override
- public void run() {
- ObjectService.methodA();
- }
- }
package com.zwz.thread.demo6;public class ThreadA extends Thread {@Overridepublic void run() {ObjectService.methodA();}
}
- package com.zwz.thread.demo6;
- public class ThreadB extends Thread {
- @Override
- public void run() {
- ObjectService.methodB();
- }
- }
package com.zwz.thread.demo6;public class ThreadB extends Thread {@Overridepublic void run() {ObjectService.methodB();}
}
- package com.zwz.thread.demo6;
- public class MainTest {
- public static void main(String[] args) {
- ThreadA a=new ThreadA();
- a.setName("A");
- a.start();
- ThreadB b=new ThreadB();
- b.setName("B");
- b.start();
- }
- }
package com.zwz.thread.demo6;public class MainTest {public static void main(String[] args) {ThreadA a=new ThreadA();a.setName("A");a.start();ThreadB b=new ThreadB();b.setName("B");b.start();}
}
运行结果:
synchronized(*.class)代码块
- package com.zwz.thread.demo7;
- public class ObjectService {
- public void methodA(){
- try {
- synchronized (ObjectService.class) {
- System.out.println("methodA begin 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());
- Thread.sleep(3000);
- System.out.println("methodA end 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- public void methodB(){
- synchronized (ObjectService.class) {
- System.out.println("methodB begin 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());
- System.out.println("methodB end 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());
- }
- }
- }
package com.zwz.thread.demo7;public class ObjectService {public void methodA(){try {synchronized (ObjectService.class) {System.out.println("methodA begin 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());Thread.sleep(3000);System.out.println("methodA end 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());}} catch (InterruptedException e) {e.printStackTrace();}}public void methodB(){synchronized (ObjectService.class) {System.out.println("methodB begin 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());System.out.println("methodB end 线程名称:"+Thread.currentThread().getName()+" times:"+System.currentTimeMillis());}}
}
- package com.zwz.thread.demo7;
- public class ThreadA extends Thread {
- private ObjectService objectService;
- public ThreadA(ObjectService objectService) {
- super();
- this.objectService = objectService;
- }
- @Override
- public void run() {
- objectService.methodA();
- }
- }
package com.zwz.thread.demo7;public class ThreadA extends Thread {private ObjectService objectService;public ThreadA(ObjectService objectService) {super();this.objectService = objectService;}@Overridepublic void run() {objectService.methodA();}
}
- package com.zwz.thread.demo7;
- public class ThreadB extends Thread {
- private ObjectService objectService;
- public ThreadB(ObjectService objectService) {
- super();
- this.objectService = objectService;
- }
- @Override
- public void run() {
- objectService.methodB();
- }
- }
package com.zwz.thread.demo7;public class ThreadB extends Thread {private ObjectService objectService;public ThreadB(ObjectService objectService) {super();this.objectService = objectService;}@Overridepublic void run() {objectService.methodB();}
}
- package com.zwz.thread.demo7;
- public class MainTest {
- public static void main(String[] args) {
- ObjectService service=new ObjectService();
- ThreadA a=new ThreadA(service);
- a.setName("A");
- a.start();
- ThreadB b=new ThreadB(service);
- b.setName("B");
- b.start();
- }
- }
package com.zwz.thread.demo7;public class MainTest {public static void main(String[] args) {ObjectService service=new ObjectService();ThreadA a=new ThreadA(service);a.setName("A");a.start();ThreadB b=new ThreadB(service);b.setName("B");b.start();}
}
运行结果:
- package com.zwz.thread.demo7;
- public class MainTest {
- public static void main(String[] args) {
- ObjectService service1=new ObjectService();
- ObjectService service2=new ObjectService();
- ThreadA a=new ThreadA(service1);
- a.setName("A");
- a.start();
- ThreadB b=new ThreadB(service2);
- b.setName("B");
- b.start();
- }
- }
package com.zwz.thread.demo7;public class MainTest {public static void main(String[] args) {ObjectService service1=new ObjectService();ObjectService service2=new ObjectService();ThreadA a=new ThreadA(service1);a.setName("A");a.start();ThreadB b=new ThreadB(service2);b.setName("B");b.start();}
}
运行结果:
转载于:https://www.cnblogs.com/firstdream/p/8334154.html
synchronized(this)、synchronized(class)与synchronized(Object)的区别相关推荐
- synchronized原理_Java并发编程 -- synchronized保证线程安全的原理
线程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要诱因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据.因此为了解决这个问题,我们可能需要这样一个方案, ...
- synchronized原理_Java并发编程—synchronized保证线程安全的原理分析
前言 程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要诱因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据.因此为了解决这个问题,我们可能需要这样一个方 ...
- java中synchronized修饰静态方法和非静态方法有什么区别?
Synchronized修饰非静态方法 Synchronized修饰非静态方法,实际上是对调用该方法的对象加锁,俗称"对象锁". Java中每个对象都有一个锁,并且是唯一的.假设分 ...
- 使用synchronized修饰静态方法和非静态方法有什么区别
前言 最近被问到了这个问题,第一次回答的也是很不好,在此参考网上答案进行整理记录.供大家学习参考. Synchronized修饰非静态方法 Synchronized修饰非静态方法,实际上是对调用该方法 ...
- 深入Synchronized和java.util.concurrent.locks.Lock的区别详解
转载自 深入Synchronized和java.util.concurrent.locks.Lock的区别详解 本篇文章是对Synchronized和java.util.concurrent.loc ...
- synchronized原理_面试必备—Synchronized 关键字使用、底层原理
在并发编程中存在线程安全问题,主要原因有: 1.存在共享数据 2.多线程共同操作共享数据 关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchro ...
- synchronized(this)和synchronized(.class)的理解
synchronized(this)和synchronized(.class)的理解 synchronized(this) 验证: 同一对象的Thread(苇名一心): 不同对象的Thread(苇名一 ...
- 既生synchronized,何生volatile (synchronized与volatile的区别)
既生synchronized,何生volatile (synchronized与volatile的区别) 我们知道,synchronized和volatile两个关键字是Java并发编程中经常用到的两 ...
- synchronized(class)、synchronized(this)与synchronized(object)的区别分析
JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.假如再细的分类,synchronized可作用于instance变量.objec ...
最新文章
- 如何成为SEO专家(10步指南)
- 框架模式 MVC 在Android中的使用
- 逻辑漏洞-token绕过
- 云原生那些顶级开源项目,你都用过哪些?
- CSS之Background-clip属性
- 自写保存字符串或文件为asp.net缓存的类
- 沙盒机制和应用程序目录
- c java 引用类型_java中的引用类型
- android跨进程关闭服务器,Android IPC机制(五)用Socket实现跨进程聊天程序
- Python 之 变量进阶(理解)
- [轉]asp解析json
- python随机森林筛选变量_如何使用虚拟变量来表示python scikit-learn随机森林中的分类数据...
- 钣金编程软件Radan无人值守,自动排版功能
- DIgSILENT出图到Matlab画图到Visio画图全过程
- python论文参考文献5篇_毕业论文参考文献
- Python调用执行Linux系统命令(四种方法)
- php开发视频直播平台技术,视频直播网站开发千万不能忘的一个知识点
- php.c drcom,Drcom (简体中文)
- 基于Sen2Cor软件的Sentinel-2大气校正
- 子比Zibll主题V6.3最新亲测免授权+可用版