Java并发编程总结1——线程状态、synchronized
以下内容主要总结自《Java多线程编程核心技术》,不定时补充更新。
一、线程的状态
Java中,线程的状态有以下6类:NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED。各状态之间的关系可用下图表示:
二、常用方法介绍
1、thread.start()和thread.run()的区别
1 public static void main(String[] args) {
2 Thread t = new Thread();
3 t.start();
4 System.out.println("main end");
5 }
调用start()方法启动线程t,t线程的状态会从New -> Runnable,t线程和main主线程同时执行。
如果把t.start()改成t.run(),则是普通的调用方法,同步执行,System.out.println("main end")语句必须等t.run()方法执行完毕之后才能执行。
注意:t.run()方法不会改变线程t的状态,也就是说线程没有启动。
2、object.wait()和thread.sleep()的区别
1 private Object obj = new Object();
2 public void testMethod() throws InterruptedException {
3 synchronized (obj) {
4 obj.wait();
5 System.out.println("testMethod end");
6 }
7 }
wait()方法主要用在synchronized同步方法或者同步块中,意味着调用object.wait()之前必须先获取锁,调用wait()方法之后释放锁,线程进入waiting状态。常见用法如上所示。如果有其他线程通过调用object.notify()或者object.notifyAll()方法时,线程必须再次获取到obj锁,然后才能继续执行obj.wait()后的语句,即打印 "testMethod end"。obj.wait(timeout)方法类似,也需要先释放锁。
wait()方法是Object类的方法,而sleep(timeout)方法是Thread类的方法。线程调用sleep(timeout)方法,状态从runnable -> timed_waiting,但是不释放锁。
3、interrupt()方法
当线程调用interrupt()方法时,只是设置了线程的中断状态。 也就是说如果线程处于runnable或者blocked状态的时候,调用interrupt()方法并不会终止线程。于是,我想当然的理解如果线程处于waiting或者timed_waiting状态时,调用interrupt方法会抛出异常,从而终止线程。
然后发现错了。见如下代码:
1 private ReentrantLock lock = new ReentrantLock();
2 private Condition condition = lock.newCondition();
3 public void testMethod() {
4 try {
5 lock.lock();
6 System.out.println("wait begin");
7 condition.awaitUninterruptibly();
8 System.out.println("wait end");
9 } finally {
10 lock.unlock();
11 }
12 }
condition.awaitUninterruptibly()方法不需要捕获InterruptedException异常,意味着如果线程通过调用awaitUninterruptibly从而使得线程状态为waiting,并不会因为调用interrupt()方法而中断。实际测试,线程状态不响应interrupt方法,只有通过condition.singal或者singalAll才能唤醒线程。
实际测试,wait(), wait(timeout), join(), sleep(timeout), await(), await(timeout)等方法都是可以被interrupt()方法中断的。
三、synchronized关键字
1、synchronized(object): 同步方法或者代码块,锁是一个对象。
2、synchronized(this): this指的是当前对象。
3、针对静态方法,比如synchronized public static void testMethod(),锁是当前的Class类。
4、如果代码抛出异常,锁自动释放。
Java并发编程总结1——线程状态、synchronized的更多相关文章
- Java并发编程系列-(2) 线程的并发工具类
2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...
- 【Java并发系列04】线程锁synchronized和Lock和volatile和Condition
img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比 ...
- 【java并发编程实战】-----线程基本概念
学习Java并发已经有一个多月了,感觉有些东西学习一会儿了就会忘记,做了一些笔记但是不系统,对于Java并发这么大的"系统",需要自己好好总结.整理才能征服它.希望同仁们一起来学习 ...
- 【Java并发编程一】线程安全和共享对象
一.什么是线程安全 当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用代码代码不必作其他的协调,这个类的行为仍然是正确的,那么称这个类是线程安全的 ...
- Java并发编程:进程和线程的由来(转)
Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程.当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通 ...
- 【Java并发编程六】线程池
一.概述 在执行并发任务时,我们可以把任务传递给一个线程池,来替代为每个并发执行的任务都启动一个新的线程,只要池里有空闲的线程,任务就会分配一个线程执行.在线程池的内部,任务被插入一个阻塞队列(Blo ...
- 【Java并发编程之深入理解】Synchronized的使用
原文:https://blog.csdn.net/zjy15203167987/article/details/82531772 1.为什么要使用synchronized 在并发编程中存在线程安全问题 ...
- Java并发编程扩展(线程通信、线程池)
之前我说过,实现多线程的方式有4种,但是之前的文章中,我只介绍了两种,那么下面这两种,可以了解了解,不懂没关系. 之前的文章-->Java并发编程之多线程 使用ExecutorService.C ...
- Java并发编程(01):线程的创建方式,状态周期管理
本文源码:GitHub·点这里 || GitEE·点这里 一.并发编程简介 1.基础概念 程序 与计算机系统操作有关的计算机程序.规程.规则,以及可能有的文件.文档及数据. 进程 进程是计算机中的程序 ...
随机推荐
- 非接触IC卡中typeA卡和typeB卡的区别--总结,二者的调制方式和编码方式不同
非接触IC卡中typeA卡和typeB卡的区别--总结,二者的调制方式和编码方式不同 1.非接触式IC卡的国际规范ISO/IEC14443的由来? 在非接触式IC卡的发展过程中,这些问题逐渐被解决并形 ...
- Linux CPU Hotplug CPU热插拔
http://blog.chinaunix.net/uid-15007890-id-106930.html CPU hotplug Support in Linux(tm) Kernel Linu ...
- android c 读写文件
1.包含头文件 #include<unistd.h>#include<sys/types.h>#include<sys/stat.h>#include<fcn ...
- svn checkout单个文件
http://www.letuknowit.com/archives/svn-checkout-single-file/ 有时候需要在svn版本仓库中某个比较上层的目录中(比如根目录)checkout ...
- unity中的构造函数
避免使用构造函数 不要在构造函数中初始化任何变量,使用Awake或Start实现这个目的.即使是在编辑模式中Unity也自动调用构造函数,这通常发生在一个脚本被编译之后,因为需要调用构造函数来取向一个 ...
- rails 数据迁移出问题
数据migrate重置 rails db:migrate:reset 具体的,,还不清楚,想起来了再去补充
- 端口报错listen eaddrinuse:::xxx
端口报错 listen eaddrinuse:::xxx 表示这个端口被占用 结束正在使用此端的程序即可.
- c++关键字volatile的作用
1.易变性 1.1概念 编译器对volatile修饰的变量,当要读取这个变量时,任何情况下都会从内存中读取,而不会从寄存器缓存中读取(因为每次都从内存中读取体现出变量的“易变”) 1.2测试代码(VS ...
- RGB转换成YCbCr
clear all; close all; clc; img=imread('colorbar.jpg');%('ngc6543a.jpg'); %img=mat2gray(img); %[0,1]; ...
- MySQL在线大表DDL操作
在线大表DDL操作的方法: 1.主从架构轮询修改 需要注意: a.主库会话级别的记录binglog的参数关闭 b.500\502错误异常捕捉 c.检查备库的second behind master是否 ...