在Java代码中经常见到synchronized这个关键字。
许多老鸟也经常使用synchronized。但是,你确定知道synchronized怎么用吗?
本文简要介绍一下synchronized的用法之作用于更小的粒度--语句块,锁定非静态实例对象
前期准备工作(包括相关工具或所使用的原料等)javasynchronizedThreadIntelliJ IDEA 详细的操作方法或具体步骤
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");
}
}
}



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

说的也对。能不能不用this,换个更容易看懂的实例行不?
好的。
Code:
class Business {
private static 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");
}
}
}

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

你说的都对。能不能创建两个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();

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

不对啊。
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();

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

- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
