java
synchronized
Thread
IntelliJ IDEA
synchronized使用于一个语句块,锁定一个静态对象的实例,是类级别的锁,同一个对象在这个语句块一次只能由一个线程执行。Talk is cheap.Show me the 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 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(); }}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); private static 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'); } }}
执行上面的代码,看看两个线程是不是串行执行的呢?是的Output:2016-03-15 23:26:35,791 [First] INFO - enter synchronized monitor2016-03-15 23:26:45,828 [First] INFO - leave synchronized monitor2016-03-15 23:26:45,828 [Second] INFO - enter synchronized monitor2016-03-15 23:26:55,828 [Second] INFO - leave synchronized monitor
执行最新的代码,看看打印的执行结果。仍然是串行执行,类级别的锁嘛。再说只是两个线程对象,Business对象的实例中有一个Output:2016-03-15 23:31:56,312 [First] INFO - enter synchronized monitor2016-03-15 23:32:06,315 [First] INFO - leave synchronized monitor2016-03-15 23:32:06,315 [Second] INFO - enter synchronized monitor2016-03-15 23:32:16,317 [Second] INFO - leave synchronized monitor
上面有篇文章有个例子,不是因为使用两个Business实例,就让两个线程由串行改为并行。synchronized锁定对象的实例是静态时,是不是也会由串行变为并行呢?Let's have a try!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();
执行最新的代码。看看打印的日志,线程有没有并行执行。是的,没有。因为这个锁加在类级别,JVM中第个类的定义是唯一的嘛,肯定是串行的了。。Output:2016-03-15 23:41:40,708 [First] INFO - enter synchronized monitor2016-03-15 23:41:50,710 [First] INFO - leave synchronized monitor2016-03-15 23:41:50,710 [Second] INFO - enter synchronized monitor2016-03-15 23:42:00,711 [Second] INFO - leave synchronized monitor