当前位置:首页 » 《随便一记》 » 正文

【并发多线程】java并发中的Synchronized关键词

17 人参与  2023年04月26日 08:01  分类 : 《随便一记》  评论

点击全文阅读


为什么要同步Synchronized关键词

如果在多线程的环境中,我们经常会遇到资源竞争的情况,比如多个线程要去同时修改同一个共享变量,这时候,就需要对资源的访问方法进行一定的处理,保证同一时间只有一个线程访问。

java提供了synchronized关键字,方便我们实现上述操作。

为什么要同步

我们举个例子,我们创建一个类,提供了一个setSum的方法:

public class SynchronizedMethods {    private int sum = 0;    public void calculate() {        setSum(getSum() + 1);    }}

如果我们在多线程的环境中调用这个calculate方法:

@Testpublic void givenMultiThread_whenNonSyncMethod() throws InterruptedException {    ExecutorService service = Executors.newFixedThreadPool(3);    SynchronizedMethods summation = new SynchronizedMethods();    IntStream.range(0, 1000)            .forEach(count -> service.submit(summation::calculate));    service.shutdown();    service.awaitTermination(1000, TimeUnit.MILLISECONDS);    assertEquals(1000, summation.getSum());}

按照上面的方法,我们预计要返回1000, 但是实际上基本不可能得到1000这个值,因为在多线程环境中,对同一个资源进行同时操作带来的不利影响。

那我们怎么才能够建线程安全的环境呢?

Synchronized关键词

java提供了多种线程安全的方法,本文主要讲解Synchronized关键词,Synchronized关键词可以有很多种形式:

Instance methodsStatic methodsCode blocks

当我们使用synchronized时,java会在相应的对象上加锁,从而在同一个对象等待锁的方法都必须顺序执行,从而保证了线程的安全。

Synchronized Instance Methods
Synchronized关键词可以放在实例方法的前面:

   public synchronized void synchronisedCalculate() {        setSum(getSum() + 1);    }

看下调用结果:

@Testpublic void givenMultiThread_whenMethodSync() {    ExecutorService service = Executors.newFixedThreadPool(3);    SynchronizedMethods method = new SynchronizedMethods();    IntStream.range(0, 1000)      .forEach(count -> service.submit(method::synchronisedCalculate));    service.awaitTermination(1000, TimeUnit.MILLISECONDS);    assertEquals(1000, method.getSum());}

这里synchronized将会锁住该方法的实例对象,多个线程中只有获得该实例对象锁的线程才能够执行。

Synchronized Static Methods
Synchronized关键词也可以用在static方法前面:

public static synchronized void syncStaticCalculate() {    staticSum = staticSum + 1;}

Synchronized放在static方法前面和实例方法前面锁住的对象不同。放在static方法前面锁住的对象是这个Class本身,因为一个Class在JVM中只会存在一个,所以不管有多少该Class的实例,在同一时刻只会有一个线程可以执行该放方法。

@Testpublic void givenMultiThread_whenStaticSyncMethod() throws InterruptedException {    ExecutorService service = Executors.newCachedThreadPool();    IntStream.range(0, 1000)            .forEach(count ->                    service.submit(SynchronizedMethods::syncStaticCalculate));    service.shutdown();    service.awaitTermination(100, TimeUnit.MILLISECONDS);    assertEquals(1000, SynchronizedMethods.staticSum);}

Synchronized Blocks
有时候,我们可能不需要Synchronize整个方法,而是同步其中的一部分,这时候,我们可以使用Synchronized Blocks:

public void performSynchronizedTask() {    synchronized (this) {        setSum(getSum() + 1);    }}

我们看下怎么测试:

@Testpublic void givenMultiThread_whenBlockSync() throws InterruptedException {    ExecutorService service = Executors.newFixedThreadPool(3);    SynchronizedMethods synchronizedBlocks = new SynchronizedMethods();    IntStream.range(0, 1000)            .forEach(count ->                    service.submit(synchronizedBlocks::performSynchronizedTask));    service.shutdown();    service.awaitTermination(100, TimeUnit.MILLISECONDS);    assertEquals(1000, synchronizedBlocks.getSum());}

上面我们同步的是实例,如果在静态方法中,我们也可以同步class:

public static void performStaticSyncTask(){    synchronized (SynchronizedMethods.class) {        staticSum = staticSum + 1;    }}

我们看下怎么测试:

@Testpublic void givenMultiThread_whenStaticSyncBlock() throws InterruptedException {    ExecutorService service = Executors.newCachedThreadPool();    IntStream.range(0, 1000)            .forEach(count ->                    service.submit(SynchronizedMethods::performStaticSyncTask));    service.shutdown();    service.awaitTermination(100, TimeUnit.MILLISECONDS);    assertEquals(1000, SynchronizedMethods.staticSum);}

点击全文阅读


本文链接:http://m.zhangshiyu.com/post/60036.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 抽卡后,气运之子怎么都缠上来了小说(夏挽棠)(抽卡后,气运之子怎么都缠上来了)全书+后续+结局在线阅读
  • 前传爱意随风消逝续集:全文+番外乔清浅宋轻舟:结局+番外新上热文
  • 宋昭黎陆铭绪(假如从没拥抱你)前文+全本完整阅读预售作品抢先看
  • 终章小说搬空海港!我携军舰嫁军官躺赢了完结篇(温婉历战)已更新+延伸(搬空海港!我携军舰嫁军官躺赢了)清爽版
  • 贵妻在上:废材老公来护航完结篇(贵妻在上:废材老公来护航)章节目录+章节前文(宋锦瑶霍少霆)全章无套路在线
  • 离婚后,前夫一家给我跪下了隐藏剧情_明白双宿双飞江城必读文_小说后续在线阅读_无删减免费完结_
  • 乔芊芊顾宴夜小说(乔芊芊顾宴夜)(踹了渣男后,禁欲大佬为我失控)前传+阅读全新作品预订
  • 假如从没拥抱你小说(宋昭黎陆铭绪)全本完整阅读最新章节(假如从没拥抱你)_笔趣阁
  • 特工医妃,摄政王的腹黑掌上欢前言+后续_苏清叙裴玄褚最新阅读_小说后续在线阅读_无删减免费完结_
  • 热文推荐绑定站姐系统后,我成娱乐巨头了附加(沈霁月沈暨星)(绑定站姐系统后,我成娱乐巨头了)最新章节列表
  • 爱你的事当做秘密惊天黑幕_鹿言裴禹连载_小说后续在线阅读_无删减免费完结_
  • 和前夫穿越后又重生了番外+结局(挽星阙靖安)小说在线阅读

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1