java线程如何释放锁_java多线程什么时候释放锁—wait()、notify()-程序员宅基地

技术标签: java线程如何释放锁  

由于等待一个锁定线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不需要锁的时候及时释放锁是很重要的。在以下情况下,持有锁的线程会释放锁:

1. 执行完同步代码块。

2. 在执行同步代码块的过程中,遇到异常而导致线程终止。

3. 在执行同步代码块的过程中,执行了锁所属对象的wait()方法,这个线程会释放锁,进行对象的等待池。

除了以上情况外,只要持有锁的此案吃还没有执行完同步代码块,就不会释放锁。因此在以下情况下,线程不会释放锁:

1. 在执行同步代码块的过程中,执行了Thread.sleep()方法,当前线程放弃CPU,开始睡眠,在睡眠中不会释放锁。

2. 在执行同步代码块的过程中,执行了Thread.yield()方法,当前线程放弃CPU,但不会释放锁。

3. 在执行同步代码块的过程中,其他线程执行了当前对象的suspend()方法,当前线程被暂停,但不会释放锁。但Thread类的suspend()方法已经被废弃。

避免死锁的一个通用的经验法则是:当几个线程都要访问共享资源A、B和C时,保证使每个线程都按照同样的顺序去访问他们,比如都先访问A,再访问B和C。

java.lang.Object类中提供了两个用于线程通信的方法:wait()和notify()。需要注意到是,wait()方法必须放在一个循环中,因为在多线程环境中,共享对象的状态随时可能改变。当一个在对象等待池中的线程被唤醒后,并不一定立即恢复运行,等到这个线程获得了锁及CPU才能继续运行,又可能此时对象的状态已经发生了变化。

# 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) {...} 代码段内。

# 调用obj.wait()后,线程A就释放了obj的锁,否则线程B无法获得obj锁,也就无法在synchronized(obj) {...} 代码段内唤醒A。

# 当obj.wait()方法返回后,线程A需要再次获得obj锁,才能继续执行。

# 如果A1,A2,A3都在obj.wait(),则B调用obj.notify()只能唤醒A1,A2,A3中的一个(具体哪一个由JVM决定)。

# obj.notifyAll()则能全部唤醒A1,A2,A3,但是要继续执行obj.wait()的下一条语句,必须获得obj锁,因此,A1,A2,A3只有一个有机会获得锁继续执行,例如A1,其余的需要等待A1释放obj锁之后才能继续执行。

# 当B调用obj.notify/notifyAll的时候,B正持有obj锁,因此,A1,A2,A3虽被唤醒,但是仍无法获得obj锁。直到B退出synchronized块,释放obj锁后,A1,A2,A3中的一个才有机会获得锁继续执行。

wait()/sleep()的区别

前面讲了wait/notify机制,Thread还有一个sleep()静态方法,它也能使线程暂停一段时间。sleep与wait的不同点是:sleep并不释放锁,并且sleep的暂停和wait暂停是不一样的。obj.wait会使线程进入obj对象的等待集合中并等待唤醒。

但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException。

如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。

需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到wait()/sleep()/join()后,就会立刻抛出InterruptedException。

Java多线程5:Synchronized锁机制

一.前言 在多线程中,有时会出现多个线程对同一个对象的变量进行并发访问的情形,如果不做正确的同步处理,那么产生的后果就是“脏读”,也就是获取到的数据其实是被修改过的. 二.引入Synchronized ...

Java多线程6:Synchronized锁代码块(this和任意对象)

一.Synchronized(this)锁代码块 用关键字synchronized修饰方法在有些情况下是有弊端的,若是执行该方法所需的时间比较长,线程1执行该方法的时候,线程2就必须等待.这种情况下就 ...

java锁之wait,notify(wait会释放锁,notify仅仅只是通知,不释放锁)

wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法 ...

java 多线程总结篇4——锁机制

在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制.Java提供了多种多线程锁机制的实现方式,常见的有synchronized.ReentrantLock.Semaphore. ...

Java多线程(三)锁对象和线程池

1:锁(Lock) 1.1       java提供了一个锁的接口,这个锁同样可以达到同步代码块的功能,API文档上说使用锁比使用synchronized更加灵活. 1.2       如何使用这个“ ...

JAVA多线程提高八:线程锁技术

前面我们讲到了synchronized:那么这节就来将lock的功效. 一.locks相关类 锁相关的类都在包java.util.concurrent.locks下,有以下类和接口: |---Abst ...

Java多线程4:synchronized锁机制

脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实是被更改过 ...

【Java多线程通信】syncrhoized下wait()/notify()与ReentrantLock下condition的用法比较

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_29745609/article/details/114596146

智能推荐

JSON.stringify 语法讲解-程序员宅基地

文章浏览阅读66次。作用:这个函数的作用主要是为了系列化对象的。可能有些人对系列化这个词过敏,我的理解很简单。就是说把原来是对象的类型转换成字符串类型(或者更确切的说是json类型的)。就这么简单。打个比方说,你有一个类,那么你可以通过这个方法转换成相应的json类型的。很简单吧。接着看。语法:[b]JSON.stringify(value [, replacer] [, space]...

《东周列国志》第五十二回 公子宋尝鼋构逆 陈灵公衵服戏朝_公子宋的记载-程序员宅基地

文章浏览阅读1k次。话说公子归生字子家,公子宋字子公,二人皆郑国贵戚之卿也。郑灵公夷元年,公子宋与归生相约早起,将入见灵公。公子宋之食指,忽然翕翕自动,何谓食指?第一指曰拇指,第三指曰中指,第四指曰无名指,第五指曰小指,惟第二指,大凡取食必用著他,故曰食指。公子宋将食指跳动之状,与归生观看,归生异之。公子宋曰:“无他。我每常若跳动,是日必尝异味。前使晋食石花鱼,后使楚一食天鹅,一食合欢橘,指皆预动,无次不验。不知今日尝何味耶?”将入朝门,内侍传命,唤宰夫甚急。公子宋问之曰:“汝唤宰夫何事?”内侍曰:“有郑客从汉江来,得一大鼋,_公子宋的记载

206265-94-3,t-Boc-N-Amido-PEG3-Tos化学式:C18H29NO7S-程序员宅基地

文章浏览阅读79次。英文名称:t-Boc-N-Amido-PEG3-Tos化学式:C18H29NO7S分子量:403.5CAS:206265-94-3纯度:95%储存条件:-20°C运输:环境温度结构式:其他产品列表:Azido-PEG4-t-Boc-hydrazide 1919045-01-4 Azido-PEG2-t-Boc-hydrazide 2100306-56-5 t-Boc-N-Amido-PEG5-propargyl 2062663-67-4 _206265-94-3

修改log4j配置文件来减小Linux系统tomcat/logs目录下的catalina.out文件的大小_catalina.out日志文件设置大小压缩-程序员宅基地

文章浏览阅读2.4k次。近两天linux下的tomcat/logs目录下catalina.out文件过大(基本上是每三个月就达到4G),除了网上找到的使用cronolog工具进行对此日志进行分割之外。也可以通过配置服务的log4j.properties文件进行屏蔽(估计这个是跟我的服务有关系,因为我的MSA服务里面打印了很多日志信息,具体log4j配置见下面)。因为我发现catalina.out文件里记录的日志都是在My_catalina.out日志文件设置大小压缩

MD5加密_md5长度-程序员宅基地

文章浏览阅读2.8w次,点赞24次,收藏257次。MD5加密MD5算法为计算机安全领域广泛使用的一种散列函数,用于提供消息的完整性,是计算机广泛使用的哈希算法之一MD5的固定长度为128比特,16字节,通常用他的16进制字面值输出他,是一个长度为32位的字符串。MD5特点长度固定(无论输入多少字节,输出总是16字节)不可逆(从结果无法反推原始数据)具有高度的离散性(输出的16字节数据,没有任何规律可言,无法预测结果)抗碰撞性(在原始数据固定的情况下,几乎不会出现两个数据的MD5相同)MD5应用场景用户密码保护:在保存用户密码时,不记_md5长度

随便推点

Redhat Linux 6 安装使用 gitlab_redfla6离线安装git-程序员宅基地

文章浏览阅读1.4k次。一、安装gitlab清华大学镜像网站下载对应的rpm包https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el6/gitlab-ce-12.0.3-ce.0.el6.x86_64.rpm[root@admin Downloads]# rpm -ivh gitlab-ce-12.0.3-ce.0.el6.x86_64.rpmwarni..._redfla6离线安装git

phpstudy_pro启动mysql后循环停止又重启_phpstudy的mysql 不停重启-程序员宅基地

文章浏览阅读3.6k次。phpstudy_pro启动mysql后循环停止又重启。最初判断是与之前安装的mysql冲突,于是把mysql卸载后删除所有相关文件和相关系统变量,重启还是没有解决问题。报错2003。然后卸载phpstudy_pro重新安装,选择一个干净的路径,没有安装过phpstudy_pro的,然后居然成功了。。..._phpstudy的mysql 不停重启

vue项目中引入video.js视频播放器_vue项目引用vr视频示例-程序员宅基地

文章浏览阅读4.5k次。vue项目中引入video.js视频播放器Video.js 是一个通用的在网页上嵌入视频播放器的 JS 库,Video.js 自动检测浏览器对 HTML5 的支持情况,如果不支持 HTML5 则自动使用 Flash 播放器。安装 : npm install video.js在main.js中引入video.jsimport Video from ‘video.js’import ..._vue项目引用vr视频示例

简单总结Linux上排查JVM问题,cpu飙升或者内存不足_内存降低cpu飙升原因排查-程序员宅基地

文章浏览阅读2.8k次,点赞2次,收藏10次。前言首先建议先简单了解JVM的内存机制,以及GC垃圾回收机制初步了解jvm的内存分配,gc以及简单的jvm内存配置以下j开头的命令基本都是java命令,如果没有设置全局环境变量,需要加上${java_home}全路径。如/usr/local/jdk8/java/bin/jmap pid一、内存不足1. 查看pidps -ef|grep java或jps -lv24130..._内存降低cpu飙升原因排查

nodejs koa2 + koa-body开发文件上传服务(图片,视频,音频....)_koa 上传音频文件-程序员宅基地

文章浏览阅读5.5k次,点赞7次,收藏36次。代码所在的项目:https://github.com/langyuxiansheng/biu-server-admin已开源在用node开发后端服务的时候,可能会用到fs文件系统.我这里用的koa2+ koa-body做的文件上传服务.废话不多说.直接上源码, 主逻辑在FilesService.js中,代码部分提供思路仅供参考.config里的配置,主要是代码中有staticPath..._koa 上传音频文件

java中double类型如果小数点后为零则显示整数否则保留两位小数_java 小数位位0展示位整数-程序员宅基地

文章浏览阅读2.6k次。public static String formatDouble(double d) { BigDecimal bg = new BigDecimal(d).setScale(2, RoundingMode.UP); double num = bg.doubleValue(); if (Math.round(num) - num == 0) { retur..._java 小数位位0展示位整数

推荐文章

热门文章

相关标签