在多线程开发中,我们经常看到synchronized(this)、synchronized(*.class)与synchronized(任意对象)这几种类型同步方法。但是是否知道这几种写法有什么区别了?下面根据代码来分析:
1、当一个线程访问ObjectService的一个synchronized (this)同步代码块时,其它线程对同一个ObjectService中其它的synchronized (this)同步代码块的访问将是堵塞,这说明synchronized (this)使用的对象监视器是一个。
2、
1、当一个线程访问ObjectService的一个synchronized (this)同步代码块时,其它线程对同一个ObjectService中其它的synchronized (this)同步代码块的访问将是堵塞,这说明synchronized (this)使用的对象监视器是一个。
2、
1、synchronized同步方法
①对其它的synchronized同步方法或synchronized(this)同步代码块调用是堵塞状态;
②同一时间只有一个线程执行synchronized同步方法中的代码。
2、synchronized(this)同步代码块
①对其它的synchronized同步方法或synchronized(this)同步代码块调用是堵塞状态;
②同一时间只有一个线程执行synchronized同步方法中的代码。
3、synchronized(任意自定义对象)
多个线程持有对象监视器作为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(任意自定义对象)同步代码快
使用synchronized(任意自定义对象)进行同步操作,对象监视器必须是同一个对象。不过不是同一个,运行就是异步执行了。
使用synchronized(任意自定义对象)进行同步操作,对象监视器必须是同一个对象。不过不是同一个,运行就是异步执行了。
4、
synchronized(*.class)代码块
同步synchronized(*.class)代码块的作用其实和synchronized static方法作用一样。Class锁对类的所有对象实例起作用。
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 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 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 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 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 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 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();
-
}
-
}
-
}
-
}
运行结果:
结论:
上面三个小例子我们可以知道,多个线程调用同一个对象中的不同名称的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 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 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 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();
-
}
-
}
-
}
运行结果:
结论:
多个线程持有对象监视器作为同一个对象的前提下,同一时间只有一个线程可以执行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 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 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 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 ThreadA extends Thread {
-
-
@Override
-
public 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 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应用在static方法上,那是对当前对应的*.Class进行持锁。
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 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 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 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();
-
}
-
}
运行结果:
结论:
同步synchronized(*.class)代码块的作用其实和synchronized static方法作用一样。Class锁对类的所有对象实例起作用。