首页 > 其他分享 >synchronized的理解及使用

synchronized的理解及使用

时间:2023-08-01 20:34:33浏览次数:25  
标签:count synchronized 代码 理解 线程 使用 修饰 方法

synchronized 是 Java 中用于实现线程同步的关键字,它可以应用于方法或代码块上。它的作用是确保在同一时间只有一个线程可以执行被 synchronized 修饰的代码,从而避免多线程并发访问共享资源导致的数据不一致或冲突问题。


理解 synchronized 的关键概念是"互斥访问"和"可见性":

1.互斥访问:当一个线程获得了 synchronized 修饰的方法或代码块的锁,其他线程就无法进入该方法或代码块,必须等待当前线程释放锁才能执行。这确保了同一时间只有一个线程可以执行被 synchronized 修饰的代码,保证了数据的一致性。
2.可见性:synchronized 除了实现互斥访问外,还具有可见性的特性。当一个线程释放锁时(例如退出 synchronized 修饰的方法或代码块),它会将对共享变量的修改刷新到主内存,使得其他线程在获取锁时能够看到最新的值。这样可以避免线程之间读取过期的数据。

Synchronized 可以以不同的方式使用:

1.同步方法:可以使用 synchronized 修饰普通方法或静态方法。修饰普通方法时,默认的锁对象是该方法所属对象实例(即当前对象)。修饰静态方法时,默认的锁对象是该方法所属的 Class 对象。当一个线程访问该方法时,它会尝试获取锁对象,如果锁未被其他线程持有,则此线程获取锁并执行方法体,否则等待锁的释放。
2.同步代码块:可以使用 synchronized 修饰代码块。使用 synchronized 块时,需要指定一个锁对象,可以是任意对象。当一个线程进入 synchronized 块时,它会尝试获取锁对象,如果锁未被其他线程持有,则此线程获取锁并执行代码块,否则等待锁的释放。通常情况下,推荐使用 synchronized 块,因为它可以控制锁的粒度,减小锁的竞争范围,提高程序性能。

 

下面是一个使用 synchronized 的示例代码:

public class SynchronizedExample {
    private int count;

    public synchronized void increment() {
        count++;
    }

    public synchronized void decrement() {
        count--;
    }

    public static void main(String[] args) {
        SynchronizedExample example = new SynchronizedExample();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                example.decrement();
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Result: " + example.count);
    }
}

在上面的示例中,increment() decrement() 方法都被修饰为 synchronized,确保每次只有一个线程可以执行这两个方法,从而保证了 count 的正确性。
需要注意的是,虽然 synchronized 能够确保线程安全性,但加锁也会引入一定的开销,并有可能导致线程的阻塞。因此,在使用 synchronized 时,需要根据实际情况进行合理的设计和权衡。
除了 synchronized,Java 还提供了其他的线程同步机制,如 LockReentrantLockReadWriteLock 等,它们提供了更多灵活和高级的特性,可以满足不同的并发控制需求。

标签:count,synchronized,代码,理解,线程,使用,修饰,方法
From: https://www.cnblogs.com/nliu/p/17598999.html

相关文章

  • SpringDataJpa对拿到的对象进行set,但是不save,数据库也能自动更新,由于使用了注解 @Tran
    SpringDataJpa对拿到的对象进行set,但是不save,数据库也能自动更新,由于使用了注解@Transactional事务进行处理原文链接:https://blog.csdn.net/qq_19903753/article/details/103367252SpringDataJpa对拿到的对象进行set,但是不save,数据库也能自动更新概述今天在进行coderev......
  • bm25算法与tf-idf比较,区别,已经使用长江
    bm25算法与tf-idf算法比较一、tf-idf算法介绍词频(TF)=某篇文章中某个关键词出现的次数/文章总字数,逆文档频率(IDF)=log(语料库文章总数/包含该关键词的文章总数+1),tfidf=tf*idf,下面给大家举个实例,你大概就明白了,例如语料库中有以下三篇文章:第一篇:张一山与杨紫疑似相恋;第二篇:C罗又......
  • 数字逻辑综合 DC 相关理解(四)
    参考《专用集成电路设计实用教程》1.多时钟同步设计时序约束以下图为例,所有的时钟都来自同一个时钟源,所以是它们是同步设计。可以看到要综合的模块输入只有CLKC,其他的时钟只作用于综合模块端口,我们需要对端口加以约束。首先约束作为综合模块的主时钟CLKC,约束语句......
  • Redis中使用Lua脚本
    一、简介Redis中为什么引入Lua脚本?Redis是高性能的key-value内存数据库,在部分场景下,是对关系数据库的良好补充。Redis提供了非常丰富的指令集,官网上提供了200多个命令。但是某些特定领域,需要扩充若干指令原子性执行时,仅使用原生命令便无法完成。Redis为这样的用户场景提供了lu......
  • Oracle中使用SQL实现日期转换(oracle中的日期转换)
    Oracle中使用SQL实现日期转换(oracle中的日期转换)原文链接:https://www.dbs724.com/260684.htmlOracle中使用SQL实现日期转换在Oracle数据库中,日期转换是一项非常重要的操作,因为不同国家和地区的日期格式不同,而且不同的应用程序需要不同的日期格式。Oracle提供了许多日期转换函......
  • 使用 Go 语言实现二叉搜索树
    原文链接:使用Go语言实现二叉搜索树二叉树是一种常见并且非常重要的数据结构,在很多项目中都能看到二叉树的身影。它有很多变种,比如红黑树,常被用作std::map和std::set的底层实现;B树和B+树,广泛应用于数据库系统中。本文要介绍的二叉搜索树用的也很多,比如在开源项目go-z......
  • 淘宝API开发系列,淘宝API商品详情的测试及使用
    为了进行淘宝的API开发,首先我们需要做下面几件事情。1)开发者注册一个账号,2)然后为每个淘宝应用注册一个应用程序键(AppKey)。3)下载淘宝API的SDK并掌握基本的API基础知识和调用,具体可以参考论坛的信息。4)利用SDK接口和对象,传入AppKey或者必要的时候获取并传入SessionKey来进行程序开......
  • 解决在macOS系统上使用rust-gdb调式rust代码时无法进入断点的问题
        问题title缩写,主要原因是gdb无法在cargo生成可执行文件和符号信息关联起来,类型信息如下图:  解决方案:在Cargo.toml文件中添加一项配置,所以能找到符号信息. 配置信息说明:1. profile.dev或者profile.release是用cargobuild进行编译时使用到的配置......
  • 在矩池云使用Llama2-7B的方法
    今天给大家分享如何在矩池云服务器使用Llama2-7b模型。硬件要求矩池云已经配置好了Llama2WebUI环境,显存需要大于8G,可以选择A4000、P100、3090以及更高配置的等显卡。租用机器在矩池云主机市场:https://matpool.com/host-market/gpu,选择显存大于8G的机器,比如A4000......
  • PHPMySQL防注入 如何使用安全的函数保护数据库
    PHPMySQL防注入如何使用安全的函数保护数据库在进行PHP编程开发时,安全性一直是开发人员必须注意的问题,其中最重要的是防止SQL注入攻击。SQL注入攻击是指通过输入恶意代码来攻击数据库的一种方式,攻击者通过输入SQL语句来绕过程序的安全机制,达到控制和操作数据库的目的。为了避免......