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

2025-12-21 15:57:23

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 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

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

3、说的也对。能不能不用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");        

        }    

    }

}

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

4、执行更改后的代码。看看执行结果有没有发生变化。

没有的。因为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

你会用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 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

你会用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 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

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

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