Java中常见的线程同步方式

在Java中,当多个线程同时访问共享资源时,为了防止数据不一致或损坏的问题,需要进行线程同步。Java提供了多种线程同步的方式,以下是一些常见的方法:

1. 使用synchronized关键字

synchronized关键字可以修饰方法或代码块,确保同一时刻只有一个线程可以执行该段代码。

  • 同步方法

    public class Counter {private int count = 0;public synchronized void increment() {count++; // 当一个线程访问这个方法时,其他线程必须等待}public synchronized int getCount() {return count;}
    }
    
  • 同步代码块

    public class Counter {private int count = 0;private final Object lock = new Object();public void increment() {synchronized(lock) {count++; // 只有获得lock对象的锁的线程才能执行这个代码块}}
    }
    

2. 使用ReentrantLock

ReentrantLockjava.util.concurrent.locks包中的一个类,提供了比synchronized更灵活的锁定机制。

import java.util.concurrent.locks.ReentrantLock;public class Counter {private final ReentrantLock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock(); // 获取锁try {count++;} finally {lock.unlock(); // 释放锁}}
}

3. 使用volatile关键字

volatile关键字确保对变量的读写操作都直接在主内存中进行,从而保证了变量的可见性。虽然volatile不提供原子性,但它在某些情况下可以用来确保线程安全。

public class Flag {private volatile boolean flag = false;public void setTrue() {flag = true; // 对flag的写操作对其他线程立即可见}public boolean check() {return flag; // 对flag的读操作直接从主内存进行}
}

4. 使用原子类

Java的java.util.concurrent.atomic包提供了一组原子类,用于在单个操作中执行复合操作,保证了操作的原子性。

import java.util.concurrent.atomic.AtomicInteger;public class Counter {private AtomicInteger count = new AtomicInteger(0);public void increment() {count.incrementAndGet(); // 原子地增加count的值}public int getCount() {return count.get();}
}

5. 使用wait()notify()方法

这两个方法定义在Object类中,用于线程间的协作。

public class Message {private String content;private boolean empty = true;public synchronized String take() {while (empty) {try {wait(); // 等待content被设置} catch (InterruptedException e) {}}empty = true;notifyAll(); // 通知其他线程content已被取走return content;}public synchronized void put(String content) {while (!empty) {try {wait(); // 等待content被取走} catch (InterruptedException e) {}}empty = false;this.content = content;notifyAll(); // 通知其他线程新的content已设置}
}

以上是Java中几种常见的线程同步方式。其实选择哪一种方式还是取决于具体的需求和场景。在设计并发程序时,需要仔细考虑数据的一致性、死锁的可能性以及性能影响,以实现高效且安全的并发控制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/792735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【nc工具信息传输】

nc,全名叫 netcat,它可以用来完成很多的网络功能,譬如端口扫描、建立TCP/UDP连接,数据传输、网络调试等等,因此,它也常被称为网络工具的 瑞士军刀 。 nc [-46DdhklnrStUuvzC] [-i interval] [-p source_po…

Linux系统Docker搭建Wiki.Js应用程序并结合cpolar实现公网访问内网知识库

文章目录 1. 安装Docker2. 获取Wiki.js镜像3. 本地服务器打开Wiki.js并添加知识库内容4. 实现公网访问Wiki.js5. 固定Wiki.js公网地址 不管是在企业中还是在自己的个人知识整理上,我们都需要通过某种方式来有条理的组织相应的知识架构,那么一个好的知识整…

zookeeper之基本命令

1、创建节点: create [-s] [-e] [-c] [-t ttl] path [data] [acl] -s: 创建一个顺序节点。顺序节点会在其路径名后加上一个递增的数字,这个数字反映了节点被创建的顺序。-e: 创建一个临时节点。临时节点在客户端会话结束时会自动被删除。-c: 创建一个容器节点。容器…

腾讯云4核8G12M服务器和标准型S5服务器配置价格表

2024年腾讯云4核8G服务器租用优惠价格:轻量应用服务器4核8G12M带宽646元15个月,CVM云服务器S5实例优惠价格1437.24元买一年送3个月,腾讯云4核8G服务器活动页面 txybk.com/go/txy 活动链接打开如下图: 腾讯云4核8G服务器优惠价格 轻…

数据结构和算法:十大排序

排序算法 排序算法用于对一组数据按照特定顺序进行排列。排序算法有着广泛的应用,因为有序数据通常能够被更高效地查找、分析和处理。 排序算法中的数据类型可以是整数、浮点数、字符或字符串等。排序的判断规则可根据需求设定,如数字大小、字符 ASCII…

关于时区一致性设置

服务器部署海外,这时候,需要考虑时区问题,很多程序地方不能写死,需要调整中间件或者服务器时区,代码使用localTime。 1、服务器 Linux CentOS7 # 设置时区 timedatectl set-timezone Europe/London# 列出伦敦 时区设置…

基于注意力整合的超声图像分割信息在乳腺肿瘤分类中的应用

基于注意力整合的超声图像分割信息在乳腺肿瘤分类中的应用 摘要引言方法 Segmentation information with attention integration for classification of breast tumor in ultrasound image 摘要 乳腺癌是世界范围内女性最常见的癌症之一。基于超声成像的计算机辅助诊断&#x…

【DevOps工具篇】使用Ansible部署Keycloak oauth2proxy 和 单点登录(SSO)设置

【DevOps工具篇】使用Ansible部署Keycloak oauth2proxy 和 单点登录(SSO)设置 目录 【DevOps工具篇】使用Ansible部署Keycloak oauth2proxy 和 单点登录(SSO)设置Ansible 基础知识部署 Keycloak创建 OIDC-客户端创建 oauth2proxy 部署顶级 Ansible PlaybookHost.iniplayboo…

prompt 工程案例

目录 prompt 工程是什么? 案例 vllm 推理加速框架 prompt 工程是什么? prompt:提示词,也就是我们使用网页版输入给大模型的内容就叫 prompt,那什么是 prompt 工程呢? 简单理解其实就是利用编写的 prom…

.NET 5种线程安全集合

在.NET中&#xff0c;有许多种线程安全的集合类&#xff0c;下面介绍五种我们常用的线程安全集合以及他们的基本用法。 ConcurrentBag ConcurrentBag 是一个线程安全的无序包。它适用于在多线程环境中频繁添加和移除元素的情况。 ConcurrentBag<int> concurrentBag n…

使用自己训练的superpoint与superglue模型进行图像配准

基于官方团队发布的预训练模型&#xff0c;使用SuperPoint与SuperGlue实现图像配准&#xff0c;可以参考https://blog.csdn.net/a486259/article/details/129093084 基于官方团队发布的代码训练自己的模型&#xff0c;可以参考https://blog.csdn.net/a486259/article/details/…

如何理解UDP 和 TCP? 区别? 应用场景?

文章目录 一、UDP二、TCP三、区别参考文献 一、UDP UDP&#xff08;User Datagram Protocol&#xff09;&#xff0c;用户数据包协议&#xff0c;是一个简单的面向数据报的通信协议&#xff0c;即对应用层交下来的报文&#xff0c;不合并&#xff0c;不拆分&#xff0c;只是在…

SQL简单优化思路

在编写SQL查询时&#xff0c;优化查询性能是一个重要的考虑因素&#xff0c;特别是在处理多表连接&#xff08;JOIN&#xff09;和子查询时。以下是一些具体的技巧和最佳实践&#xff0c;可以帮助你在保持相同返回值的前提下&#xff0c;降低SQL执行速度&#xff1a; 明确连接顺…

什么是运放噪声频率曲线?怎么算噪声有效值?只需要3个公式!

原文来自微信公众号&#xff1a;工程师看海&#xff0c;与我联系&#xff1a;chunhou0820 看海原创视频教程&#xff1a;《运放秘籍》 大家好&#xff0c;我是工程师看海&#xff0c;原创文章欢迎点赞分享&#xff01; 运放有哪些噪声源&#xff1f;什么是噪声频率曲线&#x…

使用Autodl与Xftp远程训练模型及管理远程文件

1 AutoDL网站登录创建实例 AutoDL网站:AutoDL算力云 | 弹性、好用、省钱。租GPU就上AutoDL 1&#xff09;进入算力市场&#xff0c;选取可用显卡&#xff08;工作日一般白天抢不到&#xff0c;晚上才能抢到&#xff09; 2&#xff09;选择配置环境 3&#xff09;创建成功实例…

蓝桥集训之阶乘分解

蓝桥集训之阶乘分解 核心思想&#xff1a;线性筛质数 筛出每一个质数后 只要将所有质数的1 2 3 … 次方个数都加上即可 #include <iostream>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int N 1e610;int …

python中如何使用help()

help()函数帮助我们了解模块、类型、对象、方法、属性的详细信息。 1、帮助查看类型详细信息&#xff0c;包含类的创建方式、属性、方法 >>> help(list) Help on class list in module builtins: class list(object)| list() -> new empty list| list(iterable)…

企微知识库优缺点解析:如何让其效益最大化

企业搭建企微知识库&#xff0c;作为企业内部知识的集中存储和共享平台&#xff0c;为企业带来了很多便利。但是&#xff0c;任何事物都有其两面性&#xff0c;企微知识库也不例外。今天我们就来详细探讨搭建企微知识库的优点和缺点&#xff0c;如何在使用企微知识库时使其发挥…

联达动力OA 多处任意文件上传漏洞复现

0x01 产品简介 联达动力OA是PHPOA推出的新一代OA系统,系统支持性好、安全、数据高速缓存化;支持100+应用自行安装与定义,应用表单自定义,支持应用无代码开发,支持多语言。 0x02 漏洞概述 联达动力OA /FileManage/UpLoadFile.aspx、/Hosp_Portal/uploadLogo.aspx、/Dept_Por…

7.stack容器的使用

文章目录 stack容器常用接口代码工程运行结果 stack容器 常用接口 /*1.push - 入栈*/ /*2.top - 查看栈顶元素*/ /*3.pop - 出栈*/代码工程 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<stack>using namespace std;/*1.push - 入栈*/ /*2.top…