加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 教程 > 正文

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编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读