博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程同步
阅读量:6913 次
发布时间:2019-06-27

本文共 1705 字,大约阅读时间需要 5 分钟。

hot3.png

1. 同步代码块:

为了解决并发修改临界区的问题,Java的多线程支持引入了同步监视器来解决这个问题。使用同步监视器的通用方法就是同步代码块。同步代码块的语法如下:

synchronized(obj){    ...//此处的代码就是同步代码块}

synchronized后面括号中的obj就是同步监视器。上面代码的含义:线程开始执行同步代码块之前,必须先获得对同步监视器的锁定。

2. 同步方法:

与同步代码块对应,Java的多线程安全支持还提供了同步方法,同步方法就是使用synchronized关键字来修饰某个方法,则该方法称为同步方法。对于同步方法而言,无需显式指定同步监视器,同步方法的同步监视器是this,也就是该对象本身。

3. 释放同步监视器的锁定:

任何线程进入同步代码块、同步方法之前,必须先获得对同步监视器的锁定,那么何时会释放对同步监视器的锁定呢?程序无法显式释放对同步监视器的锁定,线程会在如下几种情况下释放对同步监视器的锁定。

  • 当前线程的同步方法、同步代码块执行结束,当前线程即释放同步监视器。
  • 当前线程在同步方法、同步代码块中遇到break、return终止了该代码块、该方法的继续执行,当前线程将会释放同步监视器。
  • 当前线程在同步方法、同步代码块中出现了未处理的Error和Exception,导致了该方法、代码块异常结束时,当前线程会释放对同步监视器的锁定。
  • 当前线程执行同步代码块或同步方法时,程序执行了同步监视器对象的wait()方法,则当前线程暂停,并释放同步监视器。

在如下所示的情况下,线程不会释放同步监视器:

  • 线程执行同步代码块或同步方法时,程序调用了Thread.sleep()或Thread.yield()方法来暂停当前线程的执行,当前线程不会释放同步监视器。
  • 线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放同步监视器。当然,我们应尽量避免使用suspend()和resume()方法来控制线程。

4. 同步锁:

从Java5开始,Java提供了一种功能更强大的线程同步机制---通过显式定义同步锁对象来实现同步。在这种机制下,同步锁使用Lock对象充当。

Lock提供了比同步方法和同步代码块更广泛的锁定操作,Lock实现允许更灵活的结构,可以具有差别很大的属性,并且支持多个相关的Condition对象。

Lock是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。

某些锁可能允许对共享资源的并发访问,如ReadWriteLock。

Lock、ReadWriteLock是Java5 新提供的两个根接口,并为Lock提供了ReentrantLock实现类,为ReadWriteLock提供了ReentrantReadWriteLock实现类。

在实现线程安全的控制中,比较常用的是ReentrantLock。使用ReentrantLock对象可以显式地加锁、释放锁,通常建议使用finally块来确保在必要时释放锁。

ReentrantLock(可重入锁)具有可重入性,也就是说,一个线程可以对已被加锁的ReentrantLock锁再次加锁,ReentrantLock对象会维持一个计数器来追踪lock()方法的嵌套调用,线程在每次调用lock()加锁后,必须显式调用unlock()来释放锁,所以一段被锁保护的代码可以调用另一个被相同锁保护的方法。

虽然同步方法和同步代码块使得多线程安全编程非常方便,但有时需要以更灵活的方式使用锁。Lock提供了同步方法和同步代码块所没有的其他功能,包括用于非块结构的tryLock()方法,以及试图获取可中断锁的lockInterruptibly()方法,还有获取超时失效锁的tryLock(long time,TimeUnit unit)方法。

5. 死锁:

转载于:https://my.oschina.net/u/2914561/blog/809288

你可能感兴趣的文章
教你在Docker上不到2分钟建立一个多模型数据库!
查看>>
python输入输出语句
查看>>
HTTPS时代的到来是大势所趋!阿里云CDN如何助力企业网站进入HTTPS时代
查看>>
Linux 积极使用swap空间
查看>>
等待事件之Log File Sync
查看>>
php测试kafka
查看>>
js获取两个日期之间时间差(天数)
查看>>
Memcached 简介
查看>>
虚拟化二、Xen虚拟化技术
查看>>
Oracle 11g数据库随系统自动启动与关闭的设置方法
查看>>
git pull force
查看>>
使用new操作符来调用一个构造函数的时候发生了什么
查看>>
交换机配置vlan 访问控制列表
查看>>
Python面向对象之类的成员
查看>>
Win8上iis配置
查看>>
Confluence 6 配置 Office 转换器
查看>>
Grin交易原理详解
查看>>
大数据体系【概念认知】系列-2:存储以及副本策略
查看>>
Apache与Tomcat区别联系
查看>>
用shell编写批量打包日志脚本
查看>>