你会用java中synchronized吗--锁定非静态实例

2025-05-05 07:36:11

1、synchronized使用于一个语句块,锁定一个非静态对象的实例,是实例级别的锁,同一个对象在这个语句块一次只能由一个线弛贾班隧程执行。Talk is cheap.Show me the code.Code:package chapter2;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.util.concurrent.TimeUnit;/*** Created by MyWorld on 2016/3/14.*/public class SynchronizedDemo { public static void main(String[] args) { Business business = new Business(); Worker worker = new Worker(business); Thread threadFirst = new Thread(worker, "First"); Thread threadSecond = new Thread(worker, "Second"); threadFirst.start(); threadSecond.start(); } }class Worker implements Runnable { private Business business; public Worker(Business business) { this.business = business; } @Override public void run() { try { business.doBusiness(); } catch (InterruptedException e) { e.printStackTrace(); } } }class Business { private static Logger logger = LoggerFactory.getLogger(Business.class); public void doBusiness() throws InterruptedException { synchronized (this) { logger.info("enter synchronized monitor"); TimeUnit.SECONDS.sleep(10); logger.info("leave synchronized monitor"); } }}

你会用java中synchronized吗--锁定非静态实例
你会用java中synchronized吗--锁定非静态实例
你会用java中synchronized吗--锁定非静态实例

2、执行上面的代码,看看两个线程是否并发执行锁定的语句块了。从打印上看,是串行的。因为是实例级别的锁吗?有人问,synchronized(this)中的this是什么东东啊?就是Business这个对象的实例了。Output:2016-03-15 07:07:13,154 [First] INFO - enter synchronized monitor2016-03-15 07:07:23,156 [First] INFO - leave synchronized monitor2016-03-15 07:07:23,156 [Second] INFO - enter synchronized monitor2016-03-15 07:07:33,156 [Second] INFO - leave synchronized monitor

你会用java中synchronized吗--锁定非静态实例

3、说的也对。能不能不用this,换个更容易看莓拦肛炸懂的实例行不?好的。Code:class Business { private stat足毂忍珩ic Logger logger = LoggerFactory.getLogger(Business.class); private final byte[] lock = new byte[0]; public void doBusiness() throws InterruptedException { synchronized (lock) { logger.info("enter synchronized monitor"); TimeUnit.SECONDS.sleep(10); logger.info("leave synchronized monitor"); } }}

你会用java中synchronized吗--锁定非静态实例

4、执行更改后的代码。看看执行结果有没有发生变化。没有的。因为this和lock在虚拟机看来是一样的,都是一个实例嘛。Output:2016-03-15 07:07:13,154 [First] INFO - enter synchronized monitor2016-03-15 07:07:23,156 [First] INFO - leave synchronized monitor2016-03-15 07:07:23,156 [Second] INFO - enter synchronized monitor2016-03-15 07:07:33,156 [Second] INFO - leave synchronized monitor

你会用java中synchronized吗--锁定非静态实例

5、你说的都对。能不能创建两个Worker对象再试一下,每个Worker都是线程对象嘛?!上Code:Business business = new Business();Worker workerFirst = new Worker(business);Worker workerSecond = new Worker(business);Thread threadFirst = new Thread(workerFirst, "First");Thread threadSecond = new Thread(workerSecond, "Second");threadFirst.start();threadSecond.start();

你会用java中synchronized吗--锁定非静态实例

6、执行最新的代码。看看打印的日志,线程有没有串行执行。是的,是串行的。。Output:2016-03-15 07:21:28,760 [First] INFO - enter synchronized monitor2016-03-15 07:21:38,762 [First] INFO - leave synchronized monitor2016-03-15 07:21:38,762 [Second] INFO - enter synchronized monitor2016-03-15 07:21:48,764 [Second] INFO - leave synchronized monitor

你会用java中synchronized吗--锁定非静态实例

7、不对啊。synchronized在修饰非静态方法时,你有一个例子不是可以并行执行的,不都是实例级别的锁么?是的,这个tx是真用心学了。现在把代码改造一下,让两个线程并行执行同步代码块中的内容。既然是实例对象级别的锁,创建两个Business实例,线程执行时不就并行了。因为锁是在不同对象中的,相当于每个线程分别使用用自己独特的一把锁,两个线程各自锁定,互想没有什么关系。这样不就可以串行执行了Code:Business businessFirst = new Business();Business businessSecond = new Business();Worker workerFirst = new Worker(businessFirst);Worker workerSecond = new Worker(businessSecond);Thread threadFirst = new Thread(workerFirst, "First");Thread threadSecond = new Thread(workerSecond, "Second");threadFirst.start();threadSecond.start();

你会用java中synchronized吗--锁定非静态实例

8、执行上面最新的代码。执行中。。。。看到了吧,两个线程是同时打印了“enter synchronized monitor”是不是已经并行执行synchronized中语句了。Output:2016-03-15 07:28:58,510 [First] INFO - enter synchronized monitor2016-03-15 07:28:58,510 [Second] INFO - enter synchronized monitor2016-03-15 07:29:08,511 [First] INFO - leave synchronized monitor2016-03-15 07:29:08,511 [Second] INFO - leave synchronized monitor

你会用java中synchronized吗--锁定非静态实例
声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢