java线程同步机制
有三种方式完成同步操作:1.同步代码块。2.同步方法。3.锁机制。
同步代码块:
格式:synchronized(同步锁){ 可能会出现线程安全问题的代码(访问了共享数据的代码) }
同步锁:对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁。 1. 锁对象,可以是任意类型。2. 多个线程对象 要使用同一把锁。(注意:在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着)

同步方法:


当多个线程需要访问某个公共资源的时候,我们知道需要通过加锁来保证资源的访问不会出问题。java提供了两种方式来加锁。
一种是关键字:synchronized,一种是concurrent包下的lock锁。
synchronized是java底层支持的,而concurrent包则是jdk实现。
jvm中有三种锁:偏向锁,轻量级锁,重量级锁。
Lock锁:
Lock锁也称同步锁,加锁与释放锁方法,如下:
public void lock() :加同步锁。
public void unlock() :释放同步锁。
两者区别:最重要的是Lock是一个接口,而synchronized是一个关键字
1.Lock则完全依靠系统阻塞挂起等待线程,ReentrantLock的lock机制有2种,忽略中断锁和响应中断锁。
2.Lock底层实现基于AQS实现,采用线程独占的方式,在硬件层面依赖特殊的CPU指令(CAS)。
简单来说,ReenTrantLock的实现是一种自旋锁(状态量置1(已经在使用)或者置0的操作),通过循环调用CAS操作来实现加锁。它的性能比较好也是因为避免了使线程进入内核态的阻塞状态。想尽办法避免线程进入内核的阻塞状态是我们去分析和理解锁设计的关键钥匙。
3.Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。
4.synchronized属于重量级锁,效率低下,实现的锁机制是可重入的,主要区别是中断控制和竞争锁公平策略,Java 6 之后,为了减少获得锁和释放锁所带来的性能消耗,引入了轻量级锁和偏向锁。
5.synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),在退出同步代码块或方法时会释放该锁,Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
6.用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
7.synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)
使用如下步骤:

1.在成员位置创建一个ReentrantLock对象
2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁

Lock锁示例:
1. lock()
小结:该种方式获取锁不可中断,如果获取不到则一直休眠等待。
2.tryLock()
小结:当获取锁时,只有当该锁资源没有被其他线程持有才可以获取到,并且返回true,同时设置持有count为1;
当获取锁时,当前线程已持有该锁,那么锁可用时,返回true,同时设置持有count加1;
当获取锁时,如果其他线程持有该锁,无可用锁资源,直接返回false,这时候线程不用阻塞等待,可以先去做其他事情;
即使该锁是公平锁fairLock,使用tryLock()的方式获取锁也会是非公平的方式,只要获取锁时该锁可用那么就会直接获取并返回true。这种直接插入的特性在一些特定场景是很有用的。但是如果就是想使用公平的方式的话,可以试一试tryLock(0, TimeUnit.SECONDS),几乎跟公平锁没区别,只是会监测中断事件。
3. tryLock(long timeout, TimeUnit unit)
小结:获取锁成功或者超时之后返回。而且在公平锁和非公平锁的场景下都可以使用,只是会增加对中断事件的监测。
当获取锁时,锁资源在超时时间之内变为可用,并且在等待时没有被中断,那么当前线程成功获取锁,返回true,同时当前线程持有锁的count设置为1.
当获取锁时,在超时时间之内没有锁资源可用,那么当前线程获取失败,不再继续等待,返回false.
当获取锁时,在超时等待时间之内,被中断了,那么抛出InterruptedException,不再继续等待.
当获取锁时,在超时时间之内锁可用,并且当前线程之前已持有该锁,那么成功获取锁,同时持有count加1。
4.lockInterruptibly()
当获取锁时,锁资源可用,那么当前线程成功获得锁,同时持有count设置为1,返回true.
当获取锁时,锁资源可用,当前线程已持有该锁,它成功获取该锁,同时持有count增加1,返回true.
当获取锁时,锁资源不可用,那么该线程开始阻塞休眠等待,但是等待过程中如果有中断事件,那么会停止等待,立即返回.
当获取锁时,锁资源不可用,线程开始阻塞休眠等待,如果等待过程中锁资源变为可用,那么当前线程成功获得锁,同时持有count设置为1,返回true。
package com.mozi.corex.his.common;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SynchronizedDemo {
private Lock lock = new ReentrantLock();
public void lockTest(Thread thread) throws InterruptedException {
// lock.lock();//获取锁-----lock()是阻塞的,tryLock()是非阻塞的,调用后立即返回。
// tryLock()方法只有在成功获取了锁的情况下才会返回true,如果别的线程当前正持有锁,则会立即
//返回false!如果为这个方法加上timeout参数,则会在等待timeout的时间才会返回false
//或者在获取到锁的时候返回true。
//ReentrantLock提供了lock()、tryLock()、tryLock(long timeout,TimeUnit unit)、
// lock.lockInterruptibly()
if(lock.tryLock(3000, TimeUnit.MILLISECONDS)){//尝试获取锁,修改等待时间
try {
System.out.println(“线程”+thread.getName() + “获取当前锁”); //打印当前锁的名称
Thread.sleep(4000);//为看出执行效果,设置休眠时间
} catch (Exception e) {
System.out.println(“线程”+thread.getName() + “发生了异常释放锁”);
}finally {
System.out.println(“线程”+thread.getName() + “执行完毕释放锁”);
lock.unlock(); //释放锁
}

    }else{System.out.println(thread.getName()+"未成功,锁占用");}
}
public static void main(String[] args) {SynchronizedDemo lockTest = new SynchronizedDemo();//声明一个线程 “线程一”Thread thread1 = new Thread(new Runnable() {@Overridepublic void run() {try {lockTest.lockTest(Thread.currentThread());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}, "thread1");//声明一个线程 “线程二”Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {try {lockTest.lockTest(Thread.currentThread());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}, "thread2");// 启动2个线程thread2.start();thread1.start();}

}
结果:

注:Lock.tryLock()尝试获取锁及设定等待时间

java线程同步机制,实现同步锁相关推荐

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

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

  2. java线程join方法会释放锁吗

    java线程join方法会释放锁吗,虽然join底层使用wait,wait是释放锁的 wait()和join()的调用方的区别: object.wait()和thread.join() join()的 ...

  3. 线程同步机制synchronized中锁的判断以及锁的作用范围

    当我们使用多个线程访问同一资源(可以是同一个变量.同一个文件.同一条记录等)的时候,若多个线程只有读操作,那么不会发生线程安全问题,但是如果多个线程中对资源有读和写的操作,就容易出现线程安全问题. 要 ...

  4. java 线程 wait 一定要同步_java中使用wait就得使用同步锁,而且2个线程必须都使用同步代码块,否则就会异常...

    标签: 标题已经说明,子线程wai()时候默认的锁不是同步代码块的锁,因此wai时候显示的指明锁,现在解释看code: public class Test { //staticboolean flag ...

  5. java 线程 wait 一定要同步_Java 线程中调用wait为什么一定要在同步代码块中?

    展开全部 wait是让使用wait方法的对象等待,暂时先把对象锁给让出来,给其它持有该锁的对象用,其它对象用完后再636f707962616964757a686964616f3133333739623 ...

  6. java 线程之对象的同步和异步

    一.多线程环境下的同步与异步 同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求不到,怎么办,A线程只能等待下去. package com.jalja.org.th ...

  7. 浅谈Java多线程同步机制之同步块(方法)——synchronized

    在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法或者代码块,解决了资源共享.下面代码示意三个窗口购5张火车票: 1 package com.jikexueyuan ...

  8. Java多线程基础学习,Thread解读、java线程的状态、同步和异步、两阶段终止模式

    理论概述 单线程和多线程 为什么要使用多线程呢?多线程有什么好处呢? 如果在程序中,需要读写一个文件,该文件很大,那我们执行到该io操作时,cpu就会等待该io操作执行完才会继续运行下面的代码,进程调 ...

  9. 内核同步机制-RCU同步机制

    转自http://www.360doc.com/content/09/0805/00/36491_4675691.shtml 目录 [隐藏] 1 RCU同步机制 1.1 RCU介绍 1.2 RCU A ...

  10. java线程之可重入锁

    一.什么是可重入锁 可重入锁就是可以重复进入的锁,也叫递归锁.前提是同一把锁,如同一个类.同一个实例.同一个代码块. 来自知乎的解释:可重入锁指的是同一个线程外层函数获得锁之后,内层递归函数仍然能获取 ...

最新文章

  1. 防火墙连接的三个端口
  2. 将java项目传输到centos7服务端
  3. nginx没有worker进程_如何优雅地关闭worker进程?
  4. leetcode78. 子集(回溯)
  5. 洛谷 P1656 炸铁路
  6. mysql数据库权威指南_MySQL_MySQL权威指南读书笔记(三),第二章:MYSQL数据库里面的数 - phpStudy...
  7. Java基础学习总结(47)——JAVA输入输出流再回忆
  8. android ichartjs 曲线图,C#中利用LightningChart绘制曲线图表
  9. 免费而强大的十款PCB设计软件
  10. ScreenCapture
  11. redis命令行查询某个key值
  12. swift 图片翻转
  13. Vue Router4路由
  14. @Valid注解的使用---SpringMvc中的校验框架@valid和@validation的概念及相关使用
  15. App兼容性测试/MONKEY配置和安装
  16. 【进阶实战】用PaddlePaddle检测空气质量
  17. 2021年度训练联盟热身训练赛第一场 A.Weird Flecks, But OK (最小覆盖圆)
  18. 最简单的基于FFMPEG+SDL的音频播放器
  19. HTML相对定位与绝对定位
  20. MyBatis发展历史

热门文章

  1. 漏洞扫描技术:对Web应用程序进行漏洞扫描
  2. matlab 实现批量修改文件后缀名 案例
  3. thinkphp的商城 好在哪里
  4. php 去除 bom,php 去除文件BOM头的方法
  5. 【2020年“科创中国”】先导技术榜单、新锐企业榜单、产学研融通组织榜单发
  6. win10进入pe模式系统的操作方法
  7. Gerber文件各层的介绍
  8. C#中LitJson的使用示例 LitJson官方下载链接
  9. 移动增值短信平台实施计划方案(报业集团短信手机报)
  10. h5 +css +js +jq 基础知识总结