java 线程和线程安全初识
2017-06-15 06:48
197 查看
摘要: java 线程 安全
执行线程都是用Thread类的start()方法。
线程的5种状态
新建状态(New):线程对象被创建后,就进入了新建状态。eg,Thread = new Thread();
就绪状态(Runnable):又称可执行状态。线程对象创建后调用了start() 方法启动线程
运行状态(Running):线程获取CPU进行执行。只能从就绪状态进入运行状态。
阻塞状态(Blocked):因某种原因放弃CPU使用权,暂时停止运行。原因有三种:
等待阻塞 --> 通过调用线程的wait()或sleep()或join()方法,让线程等待某工作完成。
同步阻塞 --> 线程在获取synchronized同步锁失败(被其他线程占用)
其他阻塞 --> 通过调用线程的发出了I/O请求时,线程会进入同步阻塞状态
死亡状态(Dead):线程执行完了或异常退出了run()方法。结束生命周期
![](http://upload-images.jianshu.io/upload_images/1683839-15c1a2e80af7aeae.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
下面是java源代码中的六种状态
NEW 在执行start()方法之前
RUNNABLE 执行或等待资源
BLOCKED 线程在等待monitor锁(synchronized 关键字)
WAITING Object.wait() 和 Thread.join() 和 LockSupport.park() 方法会造成这种等待阻塞
TIMED_WAITING 暂且叫限时等待,是上面方法加了一个等待时间,或者LockSupport的其他方法
TERMINATED 终止状态·
线程可以设置为守护线程,但必须在调用 start()之前设置。
ReentrantLock 并发时,它增加了一些synchronized没有的方法,更方便管理
synchronized 简单的同步就用这个吧
interrupted()方法用来检测“当前线程”的中断状态,且会将中断状态标志清除。
isInterrupted()方法用来检测“this”的中断状态,且不会改变线程的状态标志。
获取线程终端状态 要用Thread.currentThread().isInterrupted() 比较标准
一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
volatile不能确保原子性
volatile保证有序性
在前面提到volatile关键字能禁止指令重排序,所以volatile能在一定程度上保证有序性。
volatile关键字禁止指令重排序有两层意思:
1)当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;
2)在进行指令优化时,不能将在对volatile变量的读操作或者写操作的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。
提个问题,大家可以想象想,**volatile的应用场景 ** 是什么,可以在评论区讨论哦!请关注微信公众号,查看,嘻嘻。不过以后会在评论区回复的!!
最后,建议大家多手动练练,有时候看的时候,感觉会了,但动起手来,不一定会了。
欢迎关注我的微信公众号cobs-snail,让我们一起前进吧!!
创建线程的两种方法
继承Thread类或实现Runnable接口。都是重写了 run() 方法。执行线程都是用Thread类的start()方法。
线程的5种状态
新建状态(New):线程对象被创建后,就进入了新建状态。eg,Thread = new Thread();
就绪状态(Runnable):又称可执行状态。线程对象创建后调用了start() 方法启动线程
运行状态(Running):线程获取CPU进行执行。只能从就绪状态进入运行状态。
阻塞状态(Blocked):因某种原因放弃CPU使用权,暂时停止运行。原因有三种:
等待阻塞 --> 通过调用线程的wait()或sleep()或join()方法,让线程等待某工作完成。
同步阻塞 --> 线程在获取synchronized同步锁失败(被其他线程占用)
其他阻塞 --> 通过调用线程的发出了I/O请求时,线程会进入同步阻塞状态
死亡状态(Dead):线程执行完了或异常退出了run()方法。结束生命周期
![](http://upload-images.jianshu.io/upload_images/1683839-15c1a2e80af7aeae.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
注意
这五种状态是我们认知上的五种状态,当然在程序执行中,阻塞状态就有多种类型,下面是java源代码中的六种状态
NEW 在执行start()方法之前
RUNNABLE 执行或等待资源
BLOCKED 线程在等待monitor锁(synchronized 关键字)
WAITING Object.wait() 和 Thread.join() 和 LockSupport.park() 方法会造成这种等待阻塞
TIMED_WAITING 暂且叫限时等待,是上面方法加了一个等待时间,或者LockSupport的其他方法
TERMINATED 终止状态·
线程可以设置为守护线程,但必须在调用 start()之前设置。
常用的同步类(不知道合适不合适)
CountDownLatch 通常用来使主线程等待其他线程执行完再执行所用到ReentrantLock 并发时,它增加了一些synchronized没有的方法,更方便管理
synchronized 简单的同步就用这个吧
interrupt()和 interrupted()和 isInterrupted() 区别
当某个线程调用了interrupt()方法后,相当于给该线程打上了一个中断标志,如果线程正好处于阻塞状态,会直接抛出InterruptedException 异常interrupted()方法用来检测“当前线程”的中断状态,且会将中断状态标志清除。
isInterrupted()方法用来检测“this”的中断状态,且不会改变线程的状态标志。
获取线程终端状态 要用Thread.currentThread().isInterrupted() 比较标准
volatile关键字
volatile保证可见性一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2)禁止进行指令重排序。
volatile不能确保原子性
volatile保证有序性
在前面提到volatile关键字能禁止指令重排序,所以volatile能在一定程度上保证有序性。
volatile关键字禁止指令重排序有两层意思:
1)当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;
2)在进行指令优化时,不能将在对volatile变量的读操作或者写操作的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。
提个问题,大家可以想象想,**volatile的应用场景 ** 是什么,可以在评论区讨论哦!请关注微信公众号,查看,嘻嘻。不过以后会在评论区回复的!!
最后,建议大家多手动练练,有时候看的时候,感觉会了,但动起手来,不一定会了。
欢迎关注我的微信公众号cobs-snail,让我们一起前进吧!!
![](https://static.oschina.net/uploads/img/201705/21172651_JkyP.png)
相关文章推荐
- Java多线程技术初识——7. 线程的生命周期,优先级,调度
- Java线程安全系列(1)--Servlet线程安全
- 从头认识java-17.2 基本的线程机制(1)-初识多线程-2
- Java学习之——线程非安全单利模式到线程安全单利模式
- java 线程六-解决线程安全隐患问题-加锁
- Java多线程编程--(1)初识线程
- Java线程和多线程(五)——单例类中的线程安全
- Java arraylist线程不安全 vectory 线程安全
- Java线程安全问题及线程安全解决方法
- java线程学习——线程安全(同步)
- Java多线程技术初识——2. 线程的创建
- JAVA 线程 之 初级线程安全
- Java多线程编程--(1)初识线程
- 【线程】Java线程(3)-线程安全解决方案(加锁机制)Atomic && synchronized
- 从头认识java-17.2 基本的线程机制(1)-初识多线程-1
- Java--线程--线程控制,线程安全,线程同步,线程等待,线程交互,死锁,互斥锁,读写锁
- Java多线程技术初识——3. 线程安全问题
- Java知识点总结篇:Java的内存模型、线程安全、进程和线程的区别
- Java并发(一)-- 线程安全(从“线程不安全”说起)
- Java线程和多线程(五)——单例类中的线程安全