[Java] synchronized在代码块中修饰.class与this的区别
Posted luffy5459
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Java] synchronized在代码块中修饰.class与this的区别相关的知识,希望对你有一定的参考价值。
synchronized是java中的关键字,表示同步,可以在多线程环境中起到锁的作用。它是jvm层面的锁,不需要人为获取释放锁资源,由jvm决定。
synchronized可以直接用在方法上,这种用法和synchronized在代码块中修饰this是一样的。
synchronized也可以直接用在static静态方法上,这种用法和synchronized在代码块中修饰.class类似,说类似是因为代码块粒度更小一些。
它也可以用在代码块中,这时候它可以修饰一个类对象.class,一个全局对象lock,或者this。
一般我们关注的就是修饰.class和this的区别。
修饰.class,就是表示多线程调用该类的不管什么实例,所有实例共用一把锁。
修饰this,多线程调用该类的实例,如果每个线程都有一个实例,那么每个实例都有各自的锁,他们互相不影响。如果多线程去竞争一个实例,那么这个锁就只有一把,多线程去争一个资源。
下面通过一个示例来看看他们的区别:
package com.xxx.lock;
import java.util.Date;
public class SynchronizedExample
public static void main(String[] args)
for(int i=0;i<5;i++)
BusinessService businessService = new BusinessService();
new BusinessThread(businessService).start();
static class BusinessService
public void action()
synchronized (BusinessService.class)
try
System.out.println(Thread.currentThread().getName()+" running at "+new Date());
Thread.sleep(1000);
catch (Exception e)
e.printStackTrace();
static class BusinessThread extends Thread
BusinessService businessService;
public BusinessThread(BusinessService businessService)
this.businessService = businessService;
@Override
public void run()
businessService.action();
运行结果:
Thread-0 running at Mon Oct 10 22:32:49 CST 2022
Thread-4 running at Mon Oct 10 22:32:50 CST 2022
Thread-3 running at Mon Oct 10 22:32:51 CST 2022
Thread-2 running at Mon Oct 10 22:32:52 CST 2022
Thread-1 running at Mon Oct 10 22:32:53 CST 2022
从结果可以看出,多线程调用synchronized(.class)修饰的代码块时,无论线程调用的对象实例是一个,还是多个,最终只有一个线程进入同步代码块。其他线程等待资源释放再运行。
这个地方,如果synchronized修饰this:
结果是这样的:
Thread-3 running at Mon Oct 10 22:37:41 CST 2022
Thread-2 running at Mon Oct 10 22:37:41 CST 2022
Thread-4 running at Mon Oct 10 22:37:41 CST 2022
Thread-1 running at Mon Oct 10 22:37:41 CST 2022
Thread-0 running at Mon Oct 10 22:37:41 CST 2022
五个线程几乎同时执行,因为他们各自调用的是不同的实例,而每个实例都有自己的锁,与其他实例互不干扰。
这个代码其实可以修改,就是线程创建的时候,指定对象实例为同一个。
这个时候运行结果就是多线程竞争一把锁,线程依次交替执行:
Thread-0 running at Mon Oct 10 22:50:23 CST 2022
Thread-4 running at Mon Oct 10 22:50:24 CST 2022
Thread-3 running at Mon Oct 10 22:50:25 CST 2022
Thread-2 running at Mon Oct 10 22:50:26 CST 2022
Thread-1 running at Mon Oct 10 22:50:27 CST 2022
这个时候,把synchronized修饰符改为修饰.class,结果也是一样的,线程交替执行。
从上面的示例,我们可以知道,要想多线程竞争一把锁,我们使用synchronized修饰.class、this都是可以的,但是在使用this的时候,需要注意,如果我们传递给线程的实例各不相同,那么最终同步代码块之间互不干扰 ,就没有同步的作用了。
以上是关于[Java] synchronized在代码块中修饰.class与this的区别的主要内容,如果未能解决你的问题,请参考以下文章
java 多线程9 : synchronized锁机制 之 代码块锁
[Java] synchronized在代码块中修饰.class与this的区别