Java synchronized 概括
发布时间:2021-12-11 12:22:56 所属栏目:教程 来源:互联网
导读:在Java开发的时候经常会用到关键字synchronized来对代码进行同步,在使用的过程中,对于synchronized确不是很熟悉,最近在看Spring源码时,发现有不少地方都用到同步,因此,趁此机会,研究一下。 1. synchronized锁的对象 Java中的每一个对象都可以作为锁。
在Java开发的时候经常会用到关键字synchronized来对代码进行同步,在使用的过程中,对于synchronized确不是很熟悉,最近在看Spring源码时,发现有不少地方都用到同步,因此,趁此机会,研究一下。 1. synchronized锁的对象 Java中的每一个对象都可以作为锁。 1)对于同步方法,锁是当前实例对象。 2)对于静态同步方法,锁是当前对象的Class对象。因为在Java 虚拟机中一个类只能对应一个类对象,所以同时只允许一个线程执行同一个类中的静态同步方法。 3)对于同步方法块,锁是Synchonized括号里配置的对象。 下面我们将一一根据代码来介绍这几种锁。 2. 同步实例方法 对于同步方法,锁是当前实例对象。即在同一时刻只能有一个线程可以访问该实例的同步方法。但是请注意,如果有多个实例对象,那么不同示例之间不受影响,线程可以同时访问不同示例的同步方法。看下面这段代码: package com.bj.chenfeic.concurrency; /** * 同步测试,提供了用于同步的实例方法 * * @author chenfei0801 * */ public class Sync { public synchronized void testSync() { long id = Thread.currentThread().getId(); System.out.println("线程:" + id + "进入同步块"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" + id + "退出同步块"); } } package com.bj.chenfeic.concurrency; /** * * @author chenfei0801 * */ public class SyncTread implements Runnable { @Override public void run() { Sync sync = new Sync(); sync.testSync(); } } package com.bj.chenfeic.concurrency; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * * @author chenfei0801 * */ public class SyncTest { /** * @param args */ public static void main(String[] args) { ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10); for(int i=0;i<3;i++) { newFixedThreadPool.execute(new SyncTread()); } newFixedThreadPool.shutdown(); } } 执行结果: 线程:11进入同步块 线程:13进入同步块 线程:12进入同步块 线程:13退出同步块 线程:11退出同步块 线程:12退出同步块 从执行结果中,我们可以看到testSync并没有同步,synchronized没有生效。这是因为在SyncTherd中每次都是new Sync();这样synchronized其实是作用到不同的对象上去了,所以各个线程之间其实并没有同步。 按照如下修改SynsThread、SyncTest代码,即可达到同步作用 package com.bj.chenfeic.concurrency; /** * * @author chenfei0801 * */ public class SyncTread implements Runnable { private Sync sync; public SyncTread(Sync sync) { this.sync = sync; } @Override public void run() { this.sync.testSync(); } } package com.bj.chenfeic.concurrency; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * * @author chenfei0801 * */ public class SyncTest { /** * @param args */ public static void main(String[] args) { Sync sync = new Sync();//只实例化一次 ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10); for (int i = 0; i < 3; i++) { newFixedThreadPool.execute(new SyncTread(sync)); } newFixedThreadPool.shutdown(); } } 执行结果 线程:11进入同步块 线程:11退出同步块 线程:12进入同步块 线程:12退出同步块 线程:13进入同步块 线程:13退出同步块 从上面结果中可以看出,SyncThread中使用的是同一个对象,此时线程是互斥访问testSync()方法的,即达到了同步的作用。 ![]() (编辑:PHP编程网 - 黄冈站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |