多线程JAVA篇(一)
解析AsyncTask源码之前,首先讲述与之相关的Java线程知识:
知识点清单
1、Thread类
2、Runnable接口
3、Callable接口
4、synchronized关键字
5、volatile关键字
6、Future接口
7、RunnableFuture接口
8、FutureTask类
9、线程池的相关知识
/**
* A representation of a thread's state. A given thread may only be in one
* state at a time.
*/
public enum State {
/**
* The thread has been created, but has never been started.
*/
NEW,
/**
* The thread may be run.
*/
RUNNABLE,
/**
* The thread is blocked and waiting for a lock.
*/
BLOCKED,
/**
* The thread is waiting.
*/
WAITING,
/**
* The thread is waiting for a specified amount of time.
*/
TIMED_WAITING,
/**
* The thread has been terminated.
*/
TERMINATED
}
大家发现这个枚举里面列举了六种状态,实际上线程一共只有四种状态:
1、新建(NEW):当线程被创建时,它只会短暂处于这种状态。此时它已经分配了必需的系统资源,并执行了初始化。此刻线程已经有了资格获得CPY时间,之后调度器将把这个线程转变为可运行状态或阻塞状态。
2、就绪(RUNNABLE):在这种状态下,只要调度器把时间片分配给线程,线程就可以运行。也就是说,在任意时刻,线程可以运行也可以不运行。只要调度器能分配时间片给线程,它就可以运行;这不同于死亡和阻塞状态。
3、阻塞(BLOCKED、WAITING、TIMED_WAITING):线程能够运行,但有某个条件阻止它的运行。当线程处于阻塞状态时,调度 器将会忽略线程,不会分配给线程任何CPU时间。直到线程重新进入就绪状态,它才有可能执行操作
4、死亡(TERMINATED)处于死亡或终止状态的线程将不再是可调度的,并且再也不会得到CPU时间,它的任务已结束,或不再是可运行的。任务死亡的通常方式从run方法返回,但是任务的线程还可以被中断,你将要看到这一点。
下面通过代码实例的方法为大家演示这六种状态:
public class ThreadTest { public static void main(String[] args) {
final Thread thread = new Thread(new Runnable() { @Override
public void run() {
for (int i = 0; i < 10000; i++) { } }
}); System.out.println("线程名" + thread.getName() + "线程状态" +thread.getState()); thread.start(); System.out.println("线程名" + thread.getName() + "线程状态" +thread.getState()); Thread threadTest = new Thread(new Runnable() { @Override
public void run() {
System.out.println("线程名" + thread.getName() + "线程状态" +thread.getState());
}
}); System.out.println("线程名" + threadTest.getName() + "线程状态" +threadTest.getState()); threadTest.start(); System.out.println("线程名" + thread.getName() + "线程状态" +thread.getState());
System.out.println("线程名" + threadTest.getName() + "线程状态" +threadTest.getState());
}
}
打印日志1:
线程名Thread-0线程状态NEW
线程名Thread-0线程状态RUNNABLE
线程名Thread-1线程状态NEW
线程名Thread-0线程状态TERMINATED
线程名Thread-1线程状态RUNNABLE
线程名Thread-0线程状态TERMINATED
打印日志2:
线程名Thread-0线程状态NEW
线程名Thread-0线程状态RUNNABLE
线程名Thread-1线程状态NEW
线程名Thread-0线程状态RUNNABLE
线程名Thread-1线程状态RUNNABLE
线程名Thread-0线程状态RUNNABLE
public class ThreadTestTwo { public static void main(String[] args) {
Thread thread = new Thread(new Runnable() { @Override
public void run() {
for (int i = 0; i < 1000000000; i++) { } }
}); System.out.println("线程名" + thread.getName() + "线程状态"
+ thread.getState()); thread.start(); System.out.println("线程名" + thread.getName() + "线程状态"
+ thread.getState()); try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} System.out.println("线程名" + thread.getName() + "线程状态"
+ thread.getState());
}
}
打印日志:
线程名Thread-0线程状态NEW
线程名Thread-0线程状态RUNNABLE
线程名Thread-0线程状态RUNNABLE
我来为大家分析一下这几个日志:
大家可以看到第一个线程就是thread线程,在Thread.start()方法调用之前是这个线程的状态是New(新建状态),在线程
Thread.start()方法调用之后线程的状态为Runnbale(就绪状态),在任务执行完之后状态变为Terimal(终止状态),大家可能发
现打印日志1和打印日志2略有不同,因为当线程threadTest的启动了之后,thread的任务有没有执行完成其实是一个未知不可确定的事情。这个
测试代码中还有一个知识点,大家有没有发现最后日志打印结果显示打印的最后日志竟然是Thread-0,很多人要问了最后一个日志不应该是
threadTest(Thread-1)么,其实不是因为threadTest的这个是在主线程中执行的,而有一个打印是在threadTest方法中
的,所以threadTest.run()方法中的打印日志才是最后一个,主线程的优先级是要比普通线程的优先级要高。但是不要去使用优先级去控制线程的
执行顺序,因为那并不可靠。但是因为优先级这部分使用的很少,也不是很重要,这里就不详细论述了,有兴趣的可以去看看。
通过上面这部分测试代码我们认识了线程这个类的三种状态,总结一下:
1、一个线程创建之后没有调用Thread.start()方法之前线程的状态是NEW
2、一个线程调用Thread.start()方法之后,线程的状态是RUNNABLE,无论线程是否在运行状态下线程,大家可以看第二个日志调用了Thread.sleep()方法线程的状态并没有改变可以得知
3、一个线程执行完任务之后,线程的状态就是Terimal(终结)
下面为大家讲述线程中的另外一个状态阻塞,阻塞状态又分三种(BLOCKED、WAITING、TIMED_WAITING),在讲阻塞状态之前又不可避免的先要为大家讲述一下synchronized这个关键字
多线程JAVA篇(一)的更多相关文章
- [转]有哪些值得关注的技术博客(Java篇)
有哪些值得关注的技术博客(Java篇) 大部分程序员在自学的道路上不知道走了多少坑,这个视频那个网站搞得自己晕头转向.对我个人来说我平常在学习的过程中喜欢看一些教程式的博客.这些博客的特点: 1. ...
- 面试总结——Java篇
前言:前期对Java基础的相关知识点进行了总结,具体参看:Java基础和面试知识点.近期由于笔者正在换工作(ing),因此下面将笔者在面试过程中或笔者朋友面试过程中反馈的题目进行总结,相信弄清楚下面题 ...
- JSON总结(java篇)
JSON总结(java篇一) JSON简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于 ...
- 多线程Java Socket编程示例
package org.merit.test.socket; import java.io.BufferedReader; import java.io.IOException; import jav ...
- 秒杀多线程第一篇 多线程笔试面试题汇总 ZZ 【多线程】
http://blog.csdn.net/morewindows/article/details/7392749 系列前言 本系列是本人参加微软亚洲研究院,腾讯研究院,迅雷面试时整理的,另外也加入一些 ...
- 事件驱动模型实例详解(Java篇)
或许每个软件从业者都有从学习控制台应用程序到学习可视化编程的转变过程,控制台应用程序的优点在于可以方便的练习某个语言的语法和开发习惯(如.net和java),而可视化编程的学习又可以非常方便开发出各类 ...
- 管中窥豹——框架下的SQL注入 Java篇
管中窥豹--框架下的SQL注入 Java篇 背景 SQL注入漏洞应该算是很有年代感的漏洞了,但是现在依然活跃在各大漏洞榜单中,究其原因还是数据和代码的问题. SQL 语句在DBMS系统中作为表达式被解 ...
- Java多线程(学习篇)
Java多线程:(学习篇) 1.什么是线程 2.线程状态 3.线程中断 4.线程交互 5.同步机制 6.锁机制 7.堵塞队列与堵塞栈 8.条件变量.原子量.线程池等 9.线性安全类和Callable与 ...
- Java多线程学习篇——线程的开启
随着开发项目中业务功能的增加,必然某些功能会涉及到线程以及并发编程的知识点.笔者就在现在的公司接触到了很多软硬件结合和socket通讯的项目了,很多的功能运用到了串口通讯编程,串口通讯编程的安卓端就是 ...
随机推荐
- 将插入的新行放入dataGridView的第一行
将插入的新行放入dataGridView的第一行 习惯这样用的: dataGridView1.Rows.Add(dataRow);改成:dataGridView1.Rows.Insert(0,data ...
- python遍历删除列表的方法
for item in list(somelist): somelist.remove(item)
- Js 设置class,兼容ie,火狐的方式
var trs = document.getElementsByTagName("tr"); trs[0].className="color2"; //设置c ...
- windows 装 Crypto.Cipher
python 2.7 先去官网下载,https://www.dlitz.net/software/pycrypto/ 回来装这个,http://download.csdn.net/download/d ...
- [转载]: delphi中XLSReadWrite控件的使用(1)---简介
XLSReadWrite控件简介: 一个你需要的,能在Delphi和.NET下访问Excel文件的完美解决方案. 一个经典的读写Excel的控件,对于使用Excel 开发很有帮助 官方网站: http ...
- 【转】Using Gamma 2.2
This is a detailed description of the work with Gamma 2.2. If you are only interested in exact instr ...
- Spring day02笔记
spring day01回顾 编写流程(基于xml) 1.导入jar包:4+1 --> beans/core/context/expression | commons-logging 2.编写目 ...
- js中Array对象方法详解
操作方法:concat() slice() splice() concat()方法可以基于当前数组中的所有项创建一个新数组.具体来说,这个方法会创建当前数组一个副本,将接收到参数添加到副本的末尾,最后 ...
- 使用jna调用dll,jdk位数和dll位数的关系
最近在学习jna,发现dll文件能能否成功调用取决于jdk位数. 32位jdk只能使用32位的dll,64位jdk只能使用64位的dll,否则位数不对应的话报的错是 "Exception i ...
- rediscluster 集群操作(摘抄)
一:关于redis cluster 1:redis cluster的现状 目前redis支持的cluster特性 1):节点自动发现 2):slave->master 选举,集群容错 3):Ho ...