线程、volatile与synchronized、Lock
线程
1、概念:
进程是程序运行资源分配的最小单位。
线程是CPU调度的最小单位,必须依赖于进程而存在。
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的、能独立运行的基本单位。
2、线程生命周期:
线程生命周期的5种状态:

Java线程具有五中基本状态
新建状态(New):当线程对象被创建后,即进入了新建状态,如:Thread t = new MyThread();
就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待队列中。
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
结束状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
Tip:
当调用线程的yield()方法时,线程从运行状态转换为就绪状态,但接下来CPU调度就绪状态中的哪个线程具有一定的随机性,因此,可能会出现A线程调用了yield()方法后,接下来CPU仍然调度了A线程的情况。
3、线程调度
共同点:
- wait()和sleep()他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
- wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态
不同点 - Thread类的方法:sleep(),yield()等
Object对象的方法:wait()和notify()等 - 每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。
sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法 - wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
- sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
4、线程实现
4.1、实现方式
继承Thread覆盖run()方法。
实现Runnable接口,实现run()方法。
实现Callable接口,实现call()方法。
4.2、之间的区别:
4.2.1、Thread类与Runnable接口区别:
Thread:每个线程都独立,不共享资源。
Runnable:存在线程共享概念。
4.2.2、Runnable和Callable的区别:
两者最大的不同点是:
1)是否能返回执行结果:
<font color=red>实现Callable接口的任务线程**能返回执行结果**;而实现Runnable接口的任务线程**不能返回结果**</font>;
2)方法是否能抛出异常:
Callable接口的<font color=red>call()方法**允许抛出异常**</font>;而Runnable接口的<font color=red>run()方法的异常只能在内部消化,**不能继续上抛**</font>;
5、线程安全
线程安全性包括两方面:可见性和原子性。
5.1、volatile与synchronized
5.1.1、volatile
volatile关键字解决的是内存可见性的问题:
可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
使用volatile修饰的变量会强制将修改的值立即写入主存,主存中值的更新会使缓存中的值失效。这时候会去主内存读取。
5.1.2、volatile与synchronized区别
1) volatile轻量级,只能修饰变量。synchronized重量级,可以修饰变量、方法、类。
2) volatile只能保证数据的内存可见性,不能保证原子性,因为多个线程并发访问volatile修饰的变量不会阻塞。
synchronized不仅保证内存可见性,而且还保证原子性,因为,只有获得了锁的线程才能进入临界区,从而保证临界区中的所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。
一个线程执行临界区代码过程如下:
1 获得同步锁
2 清空工作内存
3 从主存拷贝变量副本到工作内存
4 对这些变量计算
5 将变量从工作内存写回到主存
6 释放锁
所以说:仅仅使用volatile并不能保证线程安全性。而synchronized则可实现线程的安全性。
5.1、synchronized关键字的使用和缺点
1)、获取锁的线程执行完毕,然后线程释放对锁的占有
2)、线程执行发生异常,此时JVM会让线程自动释放锁
缺点:
即使大量读操作也会堵塞,不会并发去读。如果线程中有堵塞超时任务,其他任务也不会往下执行,全部堵塞了。
5.2、Lock
5.2.1、Lock接口中常用方法
lock()
tryLock() :尝试获取锁
tryLock(long time, TimeUnit unit):按照超时时间获取锁
lockInterruptibly():打断锁(注意,当一个线程获取了锁之后,是不会被interrupt()方法中断的)
unLock():释放锁
5.2.2、lock线程间的通信:
Conditon中的await()对应Object的wait();
Condition中的signal()对应Object的notify();
Condition中的signalAll()对应Object的notifyAll()
5.2.3、ReentrantLock(可重入锁)
ReentrantLock支持两种获取锁的方式,一种是公平模型,一种是非公平模型。
公平锁:保证执行顺序,先进先出,FIFO
非公平锁:JVM优化后一种插队模式,后进先出,LIFO(先进的数据可能一直消费不到)
5.2.4、ReentrantReadWriteLock (读写锁)
允许多个读线程同时访问,但不允许写线程和读线程、写线程和写线程同时访问。
相对于排他锁,提高了并发性。
在实际应用中,大部分情况下对共享数据(如缓存)的访问都是读操作远多于写操作,这时ReentrantReadWriteLock能够提供比排他锁更好的并发性和吞吐量。
5.3、lock和synchronized区别:
Lock和synchronized的选择:
| 类别 | synchronized | Lock |
|---|---|---|
| 存在层次 | Java的关键字,在jvm层面上 | 是一个接口 |
| 锁的释放 | 1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁 |
在finally中必须释放锁,不然容易造成线程死锁 |
| 锁的获取 | 假设A线程获得锁,B线程等待。 如果A线程阻塞,B线程会一直等待 |
分情况而定,Lock有多个锁获取的方式,可以尝试获得锁,线程可以不用一直等待 |
| 锁状态 | 无法判断 | 可以判断 |
| 锁类型 | 可重入 不可中断 非公平 |
可重入 可判断 可公平(两者皆可) |
| 性能 | 少量同步 | 大量同步 |
Lock可以提高多个线程进行读操作的效率。
6、守护线程
守护线程,可以理解为后台运行线程。进程结束,守护线程自然而然地就会结束,不需要手动的去关心和通知其状态。Java的垃圾回收也是一个守护线程。
它的好处就是你不需要关心它的结束问题。
线程、volatile与synchronized、Lock的更多相关文章
- Java 线程锁机制 -Synchronized Lock 互斥锁 读写锁
(1)synchronized 是互斥锁: (2)ReentrantLock 顾名思义 :可重入锁 (3)ReadWriteLock :读写锁 读写锁特点: a)多个读者可以同时进行读b)写者必须互斥 ...
- 剑指Offer——线程同步volatile与synchronized详解
(转)Java面试--线程同步volatile与synchronized详解 0. 前言 面试时很可能遇到这样一个问题:使用volatile修饰int型变量i,多个线程同时进行i++操作,这样可以实现 ...
- 线程同步的实现方式(volatile、synchronized、CountDownLatch)
题目: 自定义容器,提供新增元素(add)和获取元素数量(size)方法.启动两个线程. 线程1向容器中新增10个数据.线程2监听容器元素数量,当容器元素数量为5时,线程2输出信息并终止. 方法一:v ...
- 线程同步Volatile与Synchronized(一)
volatile 一.volatile修饰的变量具有内存可见性 volatile是变量修饰符,其修饰的变量具有内存可见性. 可见性也就是说一旦某个线程修改了该被volatile修饰的变量,它会保证修改 ...
- Java并发——线程同步Volatile与Synchronized详解
0. 前言 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52370068 面试时很可能遇到这样一个问题:使用volatile修饰in ...
- JMM内存模型+volatile+synchronized+lock
硬件内存模型: Java内存模型: 每个线程都有一个工作内存,线程只可以修改自己工作内存中的数据,然后再同步回主内存,主内存由多个内存共享. 下面 8 个操作都是原子的,不可再分的: 1) lock ...
- volatile、synchronized、lock有什么区别,以及在哪些场景下使用哪种方式?
[转]JVM锁机制volatile/synchronized/lock 1.volatile实现原理 (1)聊聊并发(一)——深入分析Volatile的实现原理 --硬件级别锁实现,Lock前缀指令会 ...
- synchronized (lock) 买票demo 线程安全
加锁防止多个线程执行同一段代码! /** http://blog.51cto.com/wyait/1916898 * @author * @since 11/10/2018 * 某电影院目前正在上映贺 ...
- 线程池 队列 synchronized
线程池 BlockingQueue synchronized volatile 本章从线程池到阻塞队列BlockingQueue.从BlockingQueue到synchronized 和 volat ...
随机推荐
- UVALive 2678 利用序列的前缀来减少时间复杂度
题意很简单,在一串正整数序列中找一个连续的子序列使该序列和大于等于一个已知量S,但要求序列长度最短,通常喜欢暴力枚举 这个题目跟大白书之前的一个题目很像,在数列A中 求 Ai-Aj最大 并且 i< ...
- UVA 10801 多线程最短路
题意:一栋摩天大楼从0层到K层,有N部电梯,每个电梯都有自己的运行速度,此外,对于某个电梯来说,并不是每一层都会停,允许在某一层进行电梯换乘,每次换乘固定消耗60秒,最终求从0层去K层的最短时间,如果 ...
- leetcode中二分查找的具体应用
给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标值,返回 [ ...
- 01 语言基础+高级:1-4 接口与多态_day09【继承、super、this、抽象类】
day09[继承.super.this.抽象类] 三大特性——继承方法重写super关键字this关键字抽象类 教学目标能够解释类名作为参数和返回值类型能够写出类的继承格式能够说出继承的特点能够说出子 ...
- PAT Advanced 1032 Sharing(25) [链表]
题目 To store English words, one method is to use linked lists and store a word letter by letter. To s ...
- 基于redis实现锁控制
多数据源 数据源1为锁控制,数据源2自定义,可用于存储. 锁:当出现并发的时候为了保证数据的一致性,不会出现并发问题,假设,用户1修改一条信息,用户2也同时修改,会按照顺序覆盖自修改的值,为了避免这种
- Java web之javascript(2020.1.6)
1.js输出: windows.alert()---警告框 document.write()---写到html文档中 innerHTML---写到HTML元素 console.log()---写到浏览 ...
- ios 真机使用相机闪退问题
需要增加权限 在info文件增加 主要前面的key 后面的cameraDesciption只是一段描述 随便写就可以
- Python实现自动处理表格,让你拥有更多的自由时间!
相信有不少朋友日常工作会用到 Excel 处理各式表格文件,更有甚者可能要花大把时间来做繁琐耗时的表格整理工作.最近有朋友问可否编程来减轻表格整理工作量,今儿我们就通过实例来实现 Python 对表格 ...
- 01 语言基础+高级:1-4 接口与多态_day10【接口、多态】&&day11【final、匿名内部类】
day10[接口.多态] 接口三大特征——多态引用类型转换 教学目标写出定义接口的格式写出实现接口的格式说出接口中成员的特点能够说出使用多态的前提条件理解多态的向上转型理解多态的向下转型 day10_ ...