java的synchronized有几种加锁方式
在Java中,synchronized关键字提供了内置的支持来实现同步访问共享资源,以避免并发问题。synchronized主要有三种加锁方式:
1.同步实例方法
当一个实例方法被声明为synchronized时,该方法将同一时间只能被一个线程访问。锁是当前对象实例(即this)。
public class SynchronizedInstanceMethod {
public synchronized void doSomething() {
// 同步代码块
// 同一时间只能有一个线程执行这里的代码
}
public static void main(String[] args) {
SynchronizedInstanceMethod obj = new SynchronizedInstanceMethod();
// 创建多个线程访问obj的doSomething方法,它们将串行执行
// ...
}
}
当我们创建了两个线程来并发地增加计数器,由于我们使用了synchronized,因此计数器的增加线程是安全的,即使两个线程都在尝试修改同一个共享变量。在同步实例方法中,锁分别是实例对象和类对象。
public class SynchronizedInstanceMethodExample {
private int count = 0;
// 同步实例方法,锁定的是当前对象的实例(this)
public synchronized void increment() {
count++;
System.out.println(Thread.currentThread().getName() + " incremented count to " + count);
}
public static void main(String[] args) {
final SynchronizedInstanceMethodExample example = new SynchronizedInstanceMethodExample();
// 创建两个线程来增加计数器
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
}, "Thread-1");
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
}, "Thread-2");
// 启动线程
thread1.start();
thread2.start();
// 等待线程完成
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出最终计数
System.out.println("Final count: " + example.count);
}
}
2.同步静态方法
当一个静态方法被声明为synchronized时,该方法将同一时间只能被一个线程访问。锁是Class对象,而不是实例对象。
public class SynchronizedStaticMethod {
public static synchronized void doSomethingStatic() {
// 同步代码块
// 同一时间只能有一个线程执行这里的代码
}
public static void main(String[] args) {
// 创建多个线程访问SynchronizedStaticMethod的doSomethingStatic方法,它们将串行执行
// ...
}
}
当我们创建了两个线程来并发地增加计数器,由于我们使用了synchronized,因此计数器的增加线程是安全的,即使两个线程都在尝试修改同一个共享变量。在同步静态方法中,锁分别也是实例对象和类对象。
public class SynchronizedStaticMethodExample {
private static int count = 0;
// 同步静态方法,锁定的是当前对象的类(Class)对象
public static synchronized void increment() {
count++;
System.out.println(Thread.currentThread().getName() + " incremented static count to " + count);
}
public static void main(String[] args) {
// 创建两个线程来增加计数器
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
increment();
}
}, "Thread-1");
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
increment();
}
}, "Thread-2");
// 启动线程...
// 等待线程完成...
// 输出最终计数...
// (与上面的例子类似,但省略了重复的代码)
}
}
3.同步代码块
我们可以使用synchronized关键字来定义一个代码块,而不是整个方法。在这种情况下,你可以指定要获取的锁对象。这提供了更细粒度的同步控制。
public class SynchronizedBlock {
private final Object lock = new Object(); // 用于同步的锁对象
public void doSomething() {
synchronized (lock) {
// 同步代码块
// 同一时间只有一个线程能够执行这里的代码
}
// 这里的代码不受同步代码块的约束
}
public static void main(String[] args) {
SynchronizedBlock obj = new SynchronizedBlock();
// 创建多个线程访问obj的doSomething方法,但只有在synchronized块中的代码将串行执行
// ...
}
}
在上面的SynchronizedBlock类中,我们创建了一个私有的Object实例lock作为锁对象。当线程进入synchronized (lock)块时,它会尝试获取lock对象的锁。如果锁已经被其他线程持有,那么该线程将被阻塞,直到锁被释放。
当我们创建了两个线程来并发地增加计数器,同步代码块的例子中,我们显式地指定了一个对象作为锁。
public class SynchronizedBlockExample {
private final Object lock = new Object(); // 用于同步的锁对象
private int count = 0;
// 同步代码块,指定了锁对象
public void increment() {
synchronized (lock) {
count++;
System.out.println(Thread.currentThread().getName() + " incremented count to " + count);
}
}
public static void main(String[] args) {
// 类似于上面的例子,但使用SynchronizedBlockExample的increment方法
// ...(省略了重复的代码)
}
}
注意:使用synchronized时应该尽量避免在持有锁的情况下执行耗时的操作,因为这会导致其他等待锁的线程长时间阻塞。同时,过度使用synchronized可能会导致性能下降,因为它会引入线程间的竞争和可能的上下文切换。在设计并发程序时,应该仔细考虑同步的粒度,并可能使用其他并发工具(如ReentrantLock、Semaphore、CountDownLatch等)来提供更细粒度的控制。
java的synchronized有几种加锁方式的更多相关文章
- 015-线程同步-synchronized几种加锁方式、Java对象头和Monitor、Mutex Lock、JDK1.6对synchronized锁的优化实现
一.synchronized概述基本使用 为确保共享变量不会出现并发问题,通常会对修改共享变量的代码块用synchronized加锁,确保同一时刻只有一个线程在修改共享变量,从而避免并发问题. syn ...
- 【转载】Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式…)介绍
转载地址:http://blog.csdn.net/truong/article/details/46711045 关键字:Redis的Java客户端Jedis的八种调用方式(事务.管道.分布式…)介 ...
- Java多线程有哪几种实现方式? Java中的类如何保证线程安全? 请说明ThreadLocal的用法和适用场景
java的同步机制,大概是通过:1.synchronized:2.Object方法中的wait,notify:3.ThreadLocal机制来实现的, 其中synchronized有两种用法:1.对类 ...
- JAVA中单例模式的几种实现方式
1 线程不安全的实现方法 首先介绍java中最基本的单例模式实现方式,我们可以在一些初级的java书中看到.这种实现方法不是线程安全的,所以在项目实践中如果涉及到线程安全就不会使用这种方式.但是如果不 ...
- 使用java配置定时任务的几种配置方式及示例
Spring定时器,主要有两种实现方式,包括Java Timer定时和Quartz定时器! 1.Java Timer定时 首先继承java.util.TimerTask类实现run方法 package ...
- Java中String对象两种赋值方式的区别
本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...
- 细说java中Map的两种迭代方式
曾经对java中迭代方式总是迷迷糊糊的,今天总算弄懂了.特意的总结了一下.基本是算是理解透彻了. 1.再说Map之前先说下Iterator: Iterator主要用于遍历(即迭代訪问)Collecti ...
- Java中Map的4种遍历方式
第一种方式:这是平常用的最多也最可取的一种遍历方式. for (Map.Entry<String, Object> entry : map.entrySet()) { System.out ...
- 基于Java的二叉树的三种遍历方式的递归与非递归实现
二叉树的遍历方式包括前序遍历.中序遍历和后序遍历,其实现方式包括递归实现和非递归实现. 前序遍历:根节点 | 左子树 | 右子树 中序遍历:左子树 | 根节点 | 右子树 后序遍历:左子树 | 右子树 ...
- Java线程池的四种创建方式
Java通过Executors提供四种线程池,分别为:newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFix ...
随机推荐
- 【Nano Framework ESP32 篇】刷入 nanoCLR 固件以及相关问题
老周在几个世纪前曾写过树莓派相关的 iOT 水文,之所以没写 Nano Framework 相关的内容,是因为那时候这货还不成熟,可玩性不高.不过,这货现在已经相对完善,老周都把它用在项目上了--第一 ...
- lattice,altera,xilinx三合一的图像转rom,mif软件
免费发一个软件, 图像转成文件. 下载地址:https://files.cnblogs.com/files/fpga-design/image_mif08030.zip
- python 远程windows系统执行cmd命令
如果你的服务器是windows系统,不想一台一台mstsc远程到桌面上去操作,python是有模块可以远程处理的:winrm pip install pywinrm 安装模块即可 windows系统服 ...
- 【Azure APIM】列举几种在APIM 策略中的主动生产的错误语句
问题描述 在为APIM服务配置了诊断日志(Diagnostic Setting),把日志收集在Log A Workspace中,需要验证日志中是否能查看到请求的错误信息. 所以想人为的来制造一些错误. ...
- few-shot-learning for object detection
github https://github.com/LiuXinyu12378/few-shot-learning-for-object-detection train.py from __futu ...
- 嘉楠k210 kd233官方demo板gpio点灯实验
使用maixpy micropython开发 import utime from Maix import GPIO from board import board_info from fpioa_m ...
- pyaudio音频录制python
python3.7不支持pyaudio pip在线安装 whl下载地址:https://github.com/intxcc/pyaudio_portaudio/releases 下载后使用pip离线安 ...
- 牛客网-SQL专项训练17
①SQL查询中使用WHere子句指出的是:查询条件 ②Mysql中表student_table(id,name,birth,sex),查询重复姓名.重复次数,并按重复次数降序排列,正确的是(A)? 解 ...
- 支付宝移动端 Hybrid 解决方案探索与实践
支付宝 Hybrid 方案建设与演进 目前支付宝有 2 套 Hybrid 方案: HTML5 容器与小程序.小程序是最近几年才出来,H5 容器已经有了很长时间的历史,所以我们就先从 H5 容器说起. ...
- 学术顶会再突破!计算平台MaxCompute论文入选国际顶会VLDB 2021
简介: VLDB 2021上,阿里云计算平台MaxCompute参与的论文入选,核心分布式调度执行引擎Fangorn.基于TVR Cost模型的通用增量计算优化器框架Tempura等分别被Indu ...