Java多线程 - 线程同步
多线程操作同一个对象时,容易引发线程安全问题。为了解决线程安全问题,Java多线程引入了同步监视器。
同步代码块
同步代码块语法格式如下:
synchronized(obj){
//此处的代码即为同步代码块
}
上面语法格式中synchronized后面括号的obj就是同步监视器,上面代码的含义是:线程开始执行同步代码块之前,必须先获得对同步监视器的锁定。
任何时刻只能有一条线程可以获得对同步监视器的锁定,当同步代码块执行结束后,该线程自然放弃了对同步监视器的锁定。
通常推荐使用可能被并发访问的共享资源当作同步监视器。
同步方法
同步方法就是用synchronized关键字来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无需显式指定同步监视器,同步方法的同步监视器是this,即当前对象本身。
需要注意的是,synchronized关键字可以修饰代码块,可以修饰方法,但是不能修饰构造器、属性等。
可变类的线程安全是以降低程序运行效率为代价的,为减少线程安全所带来的负面影响,可以使用如下策略:
- 不要对线程安全类的所有方法都进行同步,只对那些会改变共享资源的方法进行同步;
- 为可变类提供两种版本:线程安全版本和线程不安全版本,以适应不同的运行环境。
释放同步监视器的锁定
线程进入同步方法或同步代码块后无法主动释放对同步监视器的锁定,线程会在如下几种情况下释放对同步监视器的锁定:
- 同步方法、同步代码块执行结束;
- 在执行同步方法、同步代码块时遇到break、return终止了同步代码块、同步方法的执行;
- 在执行同步方法、同步代码块是遇到了Error或Exception,发生了中断;
- 在执行同步方法、同步代码块时,执行了同步监视器对象的wait()方法,则当前线程暂停、并释放同步监视器。
在下面的情况下,程序不会释放同步监视器的锁定:
- 在执行同步方法、同步代码块时,程序调用了Thread.sleep()、Thread.yield()来暂停当前线程的执行;
- 在执行同步方法、同步代码块时,其他线程调用了当前线程的suspend方法将该线程挂起。
同步锁
同步锁通过显示定义同步锁对象来实现线程同步。这里同步锁使用Lock对象充当。
通常认为,同步锁提供了比同步代码块和同步方法更广泛的锁定操作。
synchronized 方法或语句的使用提供了对与每个对象相关的隐式监视器锁的访问,但却强制所有锁获取和释放均要出现在一个块结构中:当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的词法范围内释放所有锁。
虽然 synchronized 方法和语句的范围机制使得使用监视器锁编程方便了很多,而且还帮助避免了很多涉及到锁的常见编程错误,但有时也需要以更为灵活的方式使用锁。例如,某些遍历并发访问的数据结果的算法要求使用 "hand-over-hand" 或 "chain locking":获取节点 A 的锁,然后再获取节点 B 的锁,然后释放 A 并获取 C,然后释放 B 并获取 D,依此类推。Lock 接口的实现允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁,从而支持使用这种技术。
Lock 实现提供了使用 同步方法和同步代码块所没有的其他功能,包括提供了一个非块结构的获取锁尝试 (tryLock())、一个获取可中断锁的尝试 (lockInterruptibly()) 和一个获取超时失效锁的尝试(tryLock(long, TimeUnit))。
Lock类还可以提供与隐式监视器锁完全不同的行为和语义,如保证排序、非重入用法或死锁检测。
Lock的实现类比较常用的是ReentrantLock。ReentrantLock锁具有同重入性,也就是说线程可以对它已经加锁的ReentrantLock锁再次加锁。
还有一个接口ReadWriteLock。ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。 所有 ReadWriteLock 实现都必须保证 writeLock 操作的内存同步效果也要保持与相关 readLock 的联系。也就是说,成功获取读锁的线程会看到写入锁之前版本所做的所有更新。
死锁
当两个线程互相等待对方释放同步监视器就会发生死锁。Java虚拟机没有监测,也没有采用措施来处理死锁的情况。
预防死锁,需要防止线程在等待的情况占用资源。
Java多线程 - 线程同步的更多相关文章
- Java多线程——线程同步
在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的 ...
- JAVA多线程线程同步问题
线程同步 在多线程的编程环境下,可能看着没有问题的代码在运行几千上万或者更多次后,出现了一些看着很奇怪的问题,出现这样的问题的原因就是可能会有两个或者更多个线程进入了同一块业务处理代码中导致了判断失效 ...
- Java多线程:线程同步与关键字synchronized
一.同步的特性1. 不必同步类中所有的方法, 类可以同时拥有同步和非同步方法.2. 如果线程拥有同步和非同步方法, 则非同步方法可以被多个线程自由访问而不受锁的限制. 参见实验1:http://blo ...
- Java多线程—线程同步(单信号量互斥)
JDK中Thread.State类的几种状态 线程的生命周期 线程的安全问题(同步与互斥) 方法一:同步代码块 多个线程的同步监视器(锁)必须的是同一把,任何一个类的对象都可以 syn ...
- Java多线程-线程的同步(同步方法)
线程的同步是保证多线程安全访问竞争资源的一种手段.线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些 ...
- Java多线程——线程之间的同步
Java多线程——线程之间的同步 摘要:本文主要学习多线程之间是如何同步的,如何使用volatile关键字,如何使用synchronized修饰的同步代码块和同步方法解决线程安全问题. 部分内容来自以 ...
- java 多线程—— 线程让步
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- java 多线程—— 线程等待与唤醒
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- Java 并发 线程同步
Java 并发 线程同步 @author ixenos 同步 1.异步线程本身包含了执行时需要的数据和方法,不需要外部提供的资源和方法,在执行时也不关心与其并发执行的其他线程的状态和行为 2.然而,大 ...
随机推荐
- What is Grammar?
What is Grammar? And why grammar is your friend… Grammar(noun): the structure and system of a langua ...
- c#读取excel到dataset
public DataSet TransExcelToDataSet(string fileName, List<string> sheetNames) { OleDbConnection ...
- 用jq实现鼠标移入按钮背景渐变其他的背景效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- python imageio 图片生成gif
#!/bin/python3 import matplotlib.pyplot as plt import imageio,os TIME_GAP=0.075 #两帧之间的时间间隔,秒为单位 FILE ...
- python线程间数据共享(示例演示)
``` import threading data_list = [] def task(arg): data_list.append(arg) print(data_list) def run(): ...
- Vue(5)- axios、vuex
一.内容回顾 1.webpack(前端中工作,项目上线之前对整个前端项目优化) - entry:整个项目的程序入口(main.js或index.js): - output:输出的出口: - loade ...
- 通过文件对照工具Merge数据库
项目分成线下开发版.线上測试版.线上生产版,因此相应有三个数据库. 对于一些静态数据.经常须要同步.改动了线下的开发版本号,同一时候也须要更新线上的測试版和线上生产版数据库,有时候线上的一些数据库改动 ...
- SSDT表概念具体解释
SSDT 的全称是 System Services Descriptor Table,系统服务描写叙述符表. 这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系 ...
- Web Service简单demo
最近开发因需求要求需要提供Web Service接口供外部调用,由于之前没有研究过该技术,故查阅资料研究了一番,所以写下来记录一下,方便后续使用. 这个demo采用CXF框架进行开发,后续所提到的We ...
- Selenium WebDriver 2.34.0 发布,支持Firefox22
Selenium WebDriver 2.34.0 发布,支持Firefox22http://automationqa.com/forum.php?mod=viewthread&tid=270 ...