「JAVA」Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好

JAVA多线程之并发与同步,Lock与Syncronized 说到线程,就不得不先说线程和进程的关系。进程是系统的执行单位,一般一个应用程序即是一个进程,程序启动时系统默认有一个主线程,即是UI线程,我们知道不能做耗时任务,否则ANR程序无响应。这时需要借助子线程实现,即多线程。由于线程是系统CPU的最小单位,用多线程其实就是为了更好的利用cpu的资源。一、多线程创建方式//线程休眠1000毫秒,sleep使线程进入Block状态,并释放资源xx.start();//启动线程,run函数运行@Override@Override。 阅读详情

Java 线程不安全分析及其解决方法

线程不安全

线程不安全的问题分析:在小朋友抢气球的案例中模拟网络延迟来将问题暴露出来;示例代码如下:

public class ImplementsDemo {
    public static void main(String []args) {
        Balloon balloon = new Balloon();
        new Thread(balloon, "小红").start();
        new Thread(balloon, "小强").start();
        new Thread(balloon, "小明").start();
    }
}
// 气球
class Balloon extends Thread {
	
	private int num = 50;
	
	@Override
	public void run() {
		for (int i = 0; i < 50; i++) {
        	if (num > 0) {
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
            }
          		System.out.println(Thread.currentThread().getName() + "抢到了" + (num--) + "号气球")
        	}
		}
	}
}

在线程中的run方法上不能使用throws来声明抛出异常,所以在run方法中调用有可能出现异常的代码时,只能使用try-catch将其捕获来处理。

原因是:子类覆盖父类方法时不能抛出新的异常,父类的run方法都没有抛出异常,子类就更加不能抛出异常了。详情可查看我的另一篇文章 「JAVA」运行时异常、编译时异常、自定义异常,通过案例实践转译和异常链

在上述案例中,通过引入Thread.sleep();来模拟网络延迟,该方法的作用是让当前线程进入睡眠状态10毫秒,此时其他线程就可以去抢占资源了,方法的参数是睡眠时间,以毫秒为单位。

通过观察运行结果,发现了问题:

小红、小强两个小朋友都抢到了14号气球

在运行结果中,小红、小强两个小朋友都抢到了14号气球,也就是14号气球被抢到了2次。我们来梳理线程的运行过程来看看发生了什么:

  1. 小强和小红两个线程都拿到了14号气球,由于线程调度,小强获得了CPU时间片,打印出了抢到的气球,而小红则进入睡眠;小强在打印后对num做了减一操作,此时num为13;
  2. 小明线程开始运行,抢到了13号气球,并对num做了减一操作,此时num为12;
  3. 小红线程醒来,打印出抢到的14号气球;此时的num为12,减一后结果为11;
  4. 由于多个线程是并发操作,所以对num做判断时可能上一个线程还未对num减一,故都能通过(num > 0)的判断;

然后再来运行上述代码,得出如下的结果:

运行结果中出现了本不该出现的0 和 -1

运行结果中出现了本不该出现的0和-1,因为按照正常逻辑,气球数量到1之后就不应该被打印和减一了。出现这样的结果是因为出现了以下的执行步骤:

  1. 小红、小强、小明都同时抢到了1号气球,由于线程调度,小强获取了cpu时间片,得以执行,而小明和小红则进入睡眠;小强打印出结果后,对num减一,此时num为0;
  2. 小明醒来,获得的num为0,然后小明将num打印出来,再对num减一,此时num为-1;
  3. 小红醒来,获得的num为-1,随后小红将num打印出来,再对num减一,此时怒木为-2;
  4. 由于多个线程是并发操作,所以对num做判断时可能上一个线程还未对num减一,故都能通过(num > 0)的判断;

解决方案:

在案例中的抢气球其实是两步操作:先抢到气球,再对气球总数减一;既然是两步操作,在并发中就完全有可能会被分开执行,且执行顺序无法得到控制;

想要解决上述的线程不安全的问题,就必须要将这两步操作作为一个原子操作,保证其同步运行;也就是当一个线程A进入操作的时候,其他线程只能在操作外等待,只有当线程A执行完毕,其他线程才能有机会进入操作。

原子操作:不能被分割的操作,必须保证其从一而终完全执行,要么都执行,要么都不执行。

为解决多线程并发访问同一个资源的安全性问题,Java 提供如下了几种不同的同步机制:

  1. 同步代码块;
  2. 同步方法;
  3. Lock 锁机制;

同步代码块

同步代码块: 为了保证线程能够正常执行原子操作,Java 引入了线程同步机制,其语法如下:

synchronized (同步锁) {		
        // 需要同步操作的代码  	
        ... ...
}

上述中同步锁,又称同步监听对象、同步监听器、互斥锁,同步锁是一个抽象概念,可以理解为在对象上标记了一把锁;

Java 中可以使用任何对象作为同步监听对象,但在项目开发中,我们会把当前并发访问的共享资源对象作为同步监听对象,在任何时候,最多只能运行一个线程拥有同步锁。

卫生间的使用就是一个很好的例子,一个卫生间在一段时间内只能被一个人使用,当一个人进入卫生间后,卫生间会被上锁,其他只能等待;只有当使用卫生间的人使用完毕,开锁后才能被下一个人使用。

然后就可以使用同步代码块来改写抢气球案例,示例代码如下:

public class ImplementsDemo {
    public static void main(String []args) {
        Balloon balloon = new Balloon();
        new Thread(balloon, "小红").start();
        new Thread(balloon, "小强").start();
        new Thread(balloon, "小明").start();
    }
}

// 气球
class Balloon implements Runnable {
	
	private int num = 500;
	
	@Override
	public void run() {
		for (int i = 0; i < 500; i++) {
			synchronized (this) {
				if (num > 0) {
          			System.out.println(Thread.currentThread().getName() + "抢到了" 
                     + num + "号气球");
         			 num--;
        		}
			}
        
		}
	}
}

通过查看运行结果,线程同步的问题已经得到解决。

同步方法

同步方法: 使用synchronized修饰的方法称为同步方法,能够保证当一个线程进入该方法的时候,其他线程在方法外等待。比如:

public synchronized void doSomething() {		
        // 方法逻辑	
}

PS:方法修饰符不分先后顺序。

使用同步方法来改写抢气球案例,代码如下:

public class ImplementsDemo {
    public static void main(String []args) {
        Balloon balloon = new Balloon();
        new Thread(balloon, "小红").start();
        new Thread(balloon, "小强").start();
        new Thread(balloon, "小明").start();
    }
}

// 气球
class Balloon implements Runnable {
	
	private int num = 500;
	
	@Override
	public void run() {
		for (int i = 0; i < 500; i++) {
        	grabBalloon();
		}
	}
	// 抢气球
	private synchronized void grabBalloon() {
		if (num > 0) {
			System.out.println(Thread.currentThread().getName() + "抢到了" 
							   + num + "号气球");
			num--;
		}
	}
}

注意:不能使用synchronized修改线程类中的run方法,因为使用之后,就会出现一个线程执行完了所有功能,多个线程出现串行;原本是多行道,使用synchronized修改线程类中的run方法,多行道变成了单行道。

synchronized 的好与坏

好:synchronized 保证了并发访问时的同步操作,避免了线程的安全性问题。

坏:使用synchronized 的方法、代码块的性能会比不用要低一些。

StringBuilder和StringBuffer

StringBuilder和StringBuffer 区别就在于StringBuffer中的方法都使用了synchronized修饰,StringBuilder中的方法没有使用synchronized修饰;这也是StringBuilder性能比StringBuffer高的主要原因。

Vector和ArrayList

两者都有同样的方法,有同样的实现算法,唯一不同就是Vector中的方法使用了synchronized修饰,所以Vector的性能要比ArrayList低。

Hashtable和HashMap

两者都有同样的方法,有同样的实现算法,唯一不同就是Hashtable中的方法使用了synchronized修饰,所以Hashtable的性能要比HashMap低。

volatile关键字

volatile 关键字的作用在于:被volatile 关键字修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而可以确保多个线程能正确处理该变量。

需要注意的是,volatile关键字可能会屏蔽虚拟机中的一些必要的优化操作,所以运行效率不是很高,因此,没有特别的需要,不要使用;即便使用,也要避免大量使用。

单例模式

单例模式–饿汉模式

代码如下:

public class SlackerDemo {

	private SlackerDemo() {}
	
	private static SlackerDemo instance = null;
	
	public static SlackerDemo getInstance() {
		if (instance == null) {
			instance = new SlackerDemo();
		}
		return instance;
	}
	
}

单例模式–懒汉模式

代码如下:

public class SlackerDemo {

	private SlackerDemo() {}
	
	private static SlackerDemo instance = null;
	
	public static SlackerDemo getInstance() {
		if (instance == null) {
			instance = new SlackerDemo();
		}
		return instance;
	}
	
}

懒汉模式存在线程不安全问题,在对instance对象做判断时由于并发导致出现和抢气球案例一样的问题。为了解决这个问题,使用双重检查加锁机制来解决。

双重检查加锁机制

使用“双重检查加锁”机制实现的程序,既能实现线程安全,有能够使性能不受较大的影响。那么何谓“双重检查加锁”机制?其指的是:

  • 并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才执行同步代码块,这是**第一重检查;

  • 进入同步块后,再次检查实例是否存在,如果不存在,就在同步块中创建一个实例,这是第二重检查。

这样,就只需要同步一次,减少了多次在同步情况判断所浪费的时间。

“双重检查加锁”机制的实现需要volatile关键字的配合使用,且Java 版本需要在Java 5及以上,虽然该机制可实现线程安全的单例模式,也要根据实际情况酌情使用,不宜大量推广使用。

使用“双重检查加锁”机制改写后的懒汉模式,代码如下:

public class SlackerDemo {

	private SlackerDemo() {}
	
	private static SlackerDemo instance = null;
	
	public static SlackerDemo getInstance() {
		if (instance == null) {
			synchronized (SlackerDemo.class) {
				if (instance == null) {
					instance = new SlackerDemo();
				}
			}
		}
		return instance;
	}
}

Lock 锁机制

Lock 接口

java.util.concurrent.locks包提供了Lock接口,Lock锁机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作,而且功能比synchronized代码块和synchronized方法更加强大。

官方的提供了参考价值很大的demo,能够很好的提现Lock机制的功能:

Lock 机制的官方demo

使用Lock 机制改写的抢气球案例代码如下所示:

import java.util.concurrent.locks.*;

public class LockDemo {
    public static void main(String []args) {
        Balloon balloon = new Balloon();
        new Thread(balloon, "小红").start();
        new Thread(balloon, "小强").start();
        new Thread(balloon, "小明").start();
    }
}

// 气球
class Balloon implements Runnable {
	
	private int num = 500;
	private final Lock lock = new ReentrantLock(); // 创建锁对象
	
	@Override
	public void run() {
		for (int i = 0; i < 500; i++) {
        	grabBalloon();
		}
	}
	// 抢气球
	private void grabBalloon() {
		lock.lock(); // 获取锁对象
		if (num > 0) {
			try {
				System.out.println(Thread.currentThread().getName() + "抢到了" 
							   + num + "号气球");
				num--;
			} catch (Exception e) {
				
			} finally {
				lock.unlock(); // 释放锁
			}
		}
	}
}

案例运行正常。

完结。老夫虽不正经,但老夫一身的才华!关注我,获取更多编程科技知识。

java多线程中死锁与Lock锁的用法及 synchroized与Lock的对比 死锁 多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都会停止执行的情形,某一个同步块同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题 产生死锁的四个必备条件: 1.互斥条件:一个资源每次只能被一个进程使用。 2.请求与保持条件,一个进程因请求资源而阻塞时,对已获得的资源保持不放 3.不剥夺条件;进程已获得资源,在未使用完成之前,不能强行剥夺, 4.循环等待条件:若干进程之间成一种头尾相接的循环等待资源关系。 阅读详情

相关推荐

Java 同步锁性能的最佳实践:从理论到实践的完整指南

在多线程编程中,锁是保证线程安全的重要手段之一,但如何选择合适的锁并进行优化,一直是我们面临的挑战。本博客探讨Java中同步锁的性能分析与优化之路,从使用同步锁和不使用同步锁的性能对比入手,逐步展开对锁的优化手段和技术原理的解析,帮助读者更好地理解和应用Java中的锁机制。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 10万+

21.Lock锁原理

理解AQS是打开JUC的钥匙,而如果要知道如何开门,那必须搞清楚Lock加锁和释放锁的整个过程到底是怎样的。理解了AQS的功能之后,我们再来看一下Lock锁以及几种典型锁的完整实现过程。其中look就是加锁,而tryLock就是尝试加锁,释放锁就是unlock,condition的问题,我们后面再说。在Lock接口上的注释也注明了,实现该接口主要是单个类:重入锁ReentrantLock、读写锁ReadWriteLock,另外从jdk8开始又增加了优化的读写锁StampedLock。

纵横千里 捭阖四方 的专栏 2296

Vivado 2021.1 实战:手把手教你用IEEE1735 V2加密你的Verilog源码(附完整TCL命令)

本文详细介绍了在Vivado 2021.1中使用IEEE1735 V2标准加密Verilog源码的全流程,包括许可证申请、密钥文件配置、TCL命令执行及加密后验证。通过实战步骤和完整TCL命令,帮助开发者有效保护FPGA设计知识产权,确保核心算法安全。

weixin_42706667的博客 191

Java并发之 Lock 锁

锁是一种工具,用于控制对共享资源的访问Lock和synchronized是最常见的两个锁,他们都能够达到线程安全的目录,但是使用和功能上又有较大的不同Lock接口最常见的实现类就是通常情况下Lock只允许一个线程访问共享资源,特殊情况也允许多个线程并发访问,如ReadWriteLock的ReadLock悲观锁认为:如果我不锁住这个资源,别人就会来争抢,就会造成数据结果错误,所以为了结果的正确性,悲观锁会在每次获取并修改结果时把数据锁住,让别人无法访问。

Qynwang的博客 2743

多机器人编队人工势场法协同避障算法原理及实现

ROS及SLAM进阶教程(十一)多机器人编队人工势场法协同避障算法原理及实现避障算法原理避障算法仿真 多机器人协同编队需要将理论和实践紧密地结合起来,其应用包括编队队形生成、保持、变换和路径规划与避障等等都是基于图论的理论基础完成的。 详细请参考ROS及SLAM进阶教程(八)多机器人协同编队算法原理及实现 自主避障功能是机器人编队在各种环境中保持自身安全的重要功能,在编队的基础上加入避障的功能,机器人可扫描到一定范围内的障碍物(包括其他机器人),在即将与之发生冲突时提前规避冲突,以保证自身的安全性,同时

Redglass的博客 1万+

MS17-010(Eternal blue永恒之蓝)漏洞利用+修复方法

msf永恒之蓝漏洞复现过程以及修复建议

记录学习 8512

Java中Lock锁详解

在Java中,Lock是一个接口,它提供了比关键字更高级的线程同步机制。使用Lock接口可以创建更复杂和灵活的同步结构。Lock接口的常用实现类有ReentrantLock和ReentrantReadWriteLock,它们提供了可重入的互斥锁和读写锁。使用Lock锁的一般步骤如下:1. 创建一个`Lock`对象实例。2. 在需要进行同步的代码块中,通过调用`lock()`方法来获取锁。3. 在同步的代码块执行完之后,通过调用`unlock()`方法释放锁。

mercedes_benz 8293

HRnet的pytorch实现

HRnet的pytorch实现

奋土的博客 1953

Lock锁操作机制

什么是Lock锁 Lock 锁实现提供了比使用同步方法和语句可以获得的更广泛的锁操作。它们允 许更灵活的结构,可能具有非常不同的属性,并且可能支持多个关联的条件对 象。Lock 提供了比 synchronized 更多的功能。 Lock 与的 Synchronized 区别 Lock 不是 Java 语言内置的,synchronized 是 Java 语言的关键字,因此是内置特性。Lock 是一个类,通过这个类可以实现同步访问; Lock 和 synchronized 有一点非常大的不同,采用 synch

m0_54202121的博客 2263

primetime如何做voltage scaling

存在这样的情况,标准单元库只有ssgnp0p72vm40c和ssgnp0p9vm40c的libs,但是我们希望它工作在ssgnp0p76vm40c,这样的话就需要用ssgnp0p72vm40c和ssgnp0p9vm40c的libs来scaling出ssgnp0p76vm40c的lib。

qq_34326957的博客 1685

Mplus—随机截距交叉滞后模型(Random Intercepts Cross-Lagged Panel Model, RI-CLPM)

介绍随机截距交叉滞后模型(Random Intercepts Cross-Lagged Panel Model, RI-CLPM)的相关知识,例如模型内容、Mplus语法及对应网址等。

m0_54401011的博客 9534

Java多线程详解(九)Lock锁的使用

Lock(锁) 从JDK5.0开始,Java提供了更强大的线程同步机制——通过显式定义同步锁对象来实现同步。同步锁使用Lock对象充当 java.util.locks.Lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象 ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentranrLock,可

筱寒小记 1721

微信小程序 - 实现仿小红书轮播图组件功能,类似小红书笔记页面图片展示播放效果,微信小程序仿小红书幻灯片轮播支持视频播放、图片预览,自动适应图片或视频大小可左右滑动切换(小程序精美轮播图,丝滑切换)

微信小程序,轮播图组件,微信小程序仿小红书轮播图,小红书轮播图仿造,微信小程序轮播图,微信小程序幻灯片,微信小程序高仿小红书轮播图实现,小程序实现类似小红书一样的轮播图组件,轮播图插件,精致轮播图,精美丝滑流畅切换的轮播图,轮播图组件,小红薯轮播图,关于小红书的小程序不同数量的轮播图,展示不一样的轮播指示点的实现,微信小程序仿小红书图片轮播,开发微信小程序模仿小红书,高仿小红书Banner的指示器,小红书小程序笔记详情轮播图指示点的随图片数量的变化动态变化,微信小程序swiper轮播图,js轮播图,html

✅ 精选推荐文章 6930

java 同步解决不安全类_「JAVA」Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好...

线程不安全线程不安全的问题分析:在小朋友抢气球的案例中模拟网络延迟来将问题暴露出来;示例代码如下:public class ImplementsDemo {public static void main(String []args) {Balloon balloon = new Balloon();new Thread(balloon, "小红").start();new Thread(ballo...

weixin_31156945的博客 97

基于YOLOv8的水果新鲜程度检测系统设计与实现

数据采集与预处理模块:负责收集水果图像数据并进行标注和增强深度学习模型:基于YOLOv8的目标检测模型新鲜度评估模块:根据检测结果评估水果新鲜程度用户界面:提供友好的交互界面系统集成:将各模块整合为完整系统水果新鲜程度检测需要包含多种水果在不同新鲜度状态下的图像数据集。:包含5种常见水果(苹果、香蕉、橙子、葡萄、草莓)在不同新鲜度下的图像包含约8,000张图像,分为新鲜和腐烂两类AgriVision:大型农业图像数据集,包含水果检测和分类任务Fruit-360:包含120种水果的高质量图像。

YOLO 445

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好

线程不安全 线程不安全的问题分析:在小朋友抢气球的案例中模拟网络延迟来将问题暴露出来;示例代码如下: public class ImplementsDemo { public static void main(String []args) { Balloon balloon = new Balloon(); new Thread(balloon, "小红").start(); new Thread(balloon, "小强").start();

weixin_48509270的博客 333

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

java 同步解决不安全类_Java 线程不安全分析,同步锁和Lock机制,哪个解决方案更好...

Java 线程不安全分析线程不安全线程不安全的问题分析:在小朋友抢气球的案例中模拟网络延迟来将问题暴露出来;示例代码如下:public class ImplementsDemo {public static void main(String []args){Balloon balloon = new Balloon();new Thread(balloon, "小红").start();new T...

weixin_26516551的博客 91

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【 java 多线程】同步锁 (Lock) 解决线程的安全问题

我们之前写博文总结了通过同步代码块以及同步方法的方式来实现线程的同步,从而解决线程的安全问题,今天我总结一下Lock锁来实现线程的同步!

阿牛的博客 1065

java通过lock实现同步锁

这里我们是一个卖票的演示代码 其实 同步锁 远不止一个synchronized 它本身有一个 加上锁 和释放锁的过程 为了 让我们更好的理解这个过程 JDK5之后 为我们提供了一个单独的锁工具 locklock是一个接口 他提供了 synchronized 方法 和 更广泛的语句操作lock方法 获得锁 unlock方法 释放锁ReentrantLock 类 可以实例化lock接口然后我们就来写代码演示一下在一个包下创建两个类customException 线程类 参

weixin_45966674的博客 538

Java多线程-简单使用Lock(锁)

lock是JUC(并发)下的一个接口,一般用它的实现类ReentrantLock(可重入锁)比较多。加锁:lock(),解锁:unLock(),一般放在try catch finally中使用。Lock锁>同步代码块(已经进入了方法体,分配了相应资源)>同步方法(在方法体外)

见证自己学习,成长的记录 4075

Java-多线程的使用

线程的安全前言一、基本概念:程序、进程、线程1. 概述2. 使用多线程的优点3. 何时需要多线程?二、线程的创建和使用1. Thread类的特性2. Thread类的构造器3. Thread类的有关方法与优先级3.1 方法3.2 优先级4. 创建线程的四种方式4.1 方式一:继承于Thread类(1)步骤(2)注意(3)代码演示4.2 方式二:实现Runnable接口(1)步骤(2)代码演示4.3 方式三:实现Callable接口(JDK5.0)(1)优点(2)Future接口(3)代码演示4.4 方式四:

weixin_52533007的博客 4882

C语言线程lock与unlock,谈谈线程同步Lock和unLock

Lock可以使用Condition进行线程之间的调度,它有更好的灵活性,而且在一个对象里面可以有多个Condition(即对象监视器),则线程可以注册在不同的Condition,从而可以有选择性的调度线程,更加灵活。Synchronized则使用Object对象本身的notify, wait, notityAll调度机制,相当于整个对象只有一个单一的Condition(即该对象本身)所有的线程都注...

weixin_34611130的博客 1552

解决线程安全问题——Lock锁

上一篇文章中写了同步代码块和同步方法解决线程安全,这篇文章写以下Lock锁解决线程安全。进入正题: 从JDK 5.0开始,Java提供了更强大的线程同步机制——通过显式定义同步锁对象来实现同步。同步锁使用Lock对象充当。 java.util.concurrent.locks.Lock接口是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。 举例:设置三个窗口售卖100张票 class Window5

qq_45195830的博客 745

Java多线程学习笔记(5)— “隐式同步锁(synchronized)与显式同步锁(lock)”

引入:由于在多线程开发中会出现并发问题(多个线程访问同一个资源)我们就引入了对象锁的概念,使用对象锁来实现同步,使得当前资源在某一时刻只能有一个线程访问,其他线程处于阻塞状态,只有当前对象的同步语句执行完毕后,才会释放对象锁。 一、隐式同步锁:synchronized 由于我们可以通过private 关键字来保证数据对象只能被方法访问,所以我们只需要针对方法提出一套机制, 这套机制就是synchronized关键字,它包括两种用法:synchronized方法和synchronized块, 同步方法:.

一切因为是码农 635

多线程之Lock锁

Lock锁 从JDK5.0开始,Java提供了更强大的线程同步机制,通过显示定义同步锁对象来实现同步。同步锁使用Lock对象充当。 java.util.concurrent.locks.Lock 接口时控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问。每次只能有一个线程对 Lock 对象加锁,线程开始访问共享资源前都应先获得Lock对象。 ReentrantLock 类实现了 ...

永远年轻 1205

java lock使用_Java:多线程,线程同步,同步锁(Lock)的使用(ReentrantLock、ReentrantReadWriteLock)...

关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。本文探讨Lock对象。synchronized与java.util.concurrent.locks.Lock 的相同点:Lock能完成synchronized所实现的所有功能;主要不同点:Lock有比synchronized更精确的线程语义和更...

weixin_31655833的博客 187
上一篇: Spark 3.0发布啦,改进SQL,弃Python 2,更好的兼容ANSI SQL,性能大幅提升
下一篇: 「JAVA」通过实现生产者、消费者案例再次实践Java 多线程
老夫不正经
博客等级 码龄10年 13粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值