线程的状态
状态名称 | 说明 |
---|---|
new | 初始状态:线程被构建,但没有调用start()方法 |
runnable | 运行状态:就绪和运行统称“运行中” |
blocked | 阻塞状态:线程阻塞于锁 |
waiting | 等待状态:线程进入等待状态,需要等待其他线程通知或中断 |
time_waiting | 超时等待状态:指定时间自行返回 |
terminated | 终止状态:线程已执行完毕 |
1. 线程创建后,调用start()开始运行,进入运行状态;
2. 执行wait()方法后,进入等待状态;
3. 进入等待状态的线程需要其他线程通知才能返回运行状态;
4. 如果是超时等待状态,超时后会返回运行状态;
5. 调用同步方式,没有获得锁(synchronized),则进入阻塞状态;
6. 如果是锁是Lock接口的,则进入等待状态;
7. 执行Runnable的run()后,进入终止状态;
启动 & 终止
构造线程
private void init(String name,ThreadGroup g,Runnable target){
if(name == null){
throw new NullPointerException("name cannot be null")
}
//当前线程为父线程
Thread parent = currentThread();
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
this.name = name.toCharArray();
this.target = target;
setPriority(priority);
//复制父线程的InheritableThreadLocal
if(parent.inheritableThreadLocals != null){
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
}
//分配线程ID
tid = nextThreadID();
}
启动线程:调用start()方法即可启动线程
终止线程
public static void main(String[] args)throws Exception{
Runner one = new Runner();
Thread countThread = new Thread(one,"CountThread");
countThread.start();
TimeUnit.SECONDS.sleep(1); //睡眠1秒,main线程对CountThread进行中断,使countThread能够感知中断而结束
countThread.interrupt();
Runner two = new Runner();
countThread = new Thread(two,"CountThread");
countThread.start();
TimeUnit.SECONDS.sleep(1); //睡眠1秒,main线程Runner two进行cancel,使countThread能够感知on为false而结束
two.cancel();
}
private static class Runner implements Runnable{
private long i;
private volatile boolean on = true;
@Override
public void run(){
while(on && !Thread.currentThread().isInterrupted()){
i++;
}
System.out.println("Count i = " + i);
}
public void cancel(){
on = false;
}
}
线程间通信
等待 / 通知 机制
static boolean flag = true;
static Object lock = new Object();
public static main(String[] args)throws Exception{
Thread waitThread = new Thread(new Wait(),"WaitThread");
waitThread.start();
TimeUnit.SECONDS.sleep(1);
Thread notifyThread = new Thread(new Notify(),"NotifyThread");
notifyThread.start();
}
static class Wait implements Runnable{
public void run(){
synchronized(lock){
while(flag){
try{
System.out.println(Thread.currentThread() + " wait");
lock.wait();
}catch(InterruptedException e){ }
}
System.out.println(Thread.currentThread() + " run");
}
}
}
static class Notity implements Runnable{
public void run(){
synchronized(lock){
System.out.println(Thread.currentThread() + " notify");
lock.notifyAll();
flag = false;
SleepUtils.senond(5);
}
synchronized(lock){
System.out.println(Thread.currentThread() + " hold lock again");
}
}
}
管道输入 / 输出流
public static void main(String[] args)throws Exception{
PipedWriter out = new PipedWriter();
PipedReader in = new PipedReader();
out.connect(in);
Thread printThread = new Thread(new Print(in),"PrintThread");
printThread.start();
int receive = 0;
try{
while((receive = System.in.read()) != -1){
out.write(receive);
}
}finally{
out.close();
}
}
static class Print implements Runnable{
private PipedReader in;
public Print(PipedReader in){
this.in = in;
}
public void run(){
int receive = 0;
try{
while((receive = in.read) != -1){
System.out.print((char)receive);
}
}catch(IOException e){ }
}
}
Thread.join()
线程A执行thread.join():线程A等待thread线程终止后才从thread.join()返回
public static void main(String[] args)throws Exception{
Thread previous = Thread.currentThread();
for(int i = 0; i < 10; i++){
Thread thread = new Thread(new Domino(previous),String.valueOf(i));
thread.start();
previous = thread;
}
TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName() + " terminate.");
}
static class Domino implements Runnable{
private Thread thread;
public Domino(Thread thread){
this.thread = thread;
}
public void run(){
try{
thread.join();
}catch(InterruptedException e){ }
System.out.println(Thread.currentThread().getName() + " terminate.");
}
}
ThreadLocal
public class Profiler{
private static final ThreadLocal<long> TIME_THREADLOCAL = new ThreadLocal<long>(){
protected Long initialValue(){
return System.currentTimeMillis();
}
}
public static final void begin(){
TIME_THREADLOCAL.set(System.currentTimeMillis());
}
public static final long end(){
return System.currentTimeMillis() - TIME_THREADLOCAL.get();
}
public static void main(String[] args)throws Exception{
Profiler.begin();
TimeUnit.SECONDS.sleep(1);
System.out.println("Cost: " + Profiler.end() + " mills");
}
}
小结
线程的生命周期中有6中不同状态,指定时刻,只能处在一个状态;
线程的相互配合需要线程间的通信,等待/通知机制可以得到生产者消费者的效果,管道输入输出流可以在线程间进行数据传输,Thread.join()有等待插入线程完成的效果,ThreadLocal是附带在线程上的变量,可以让线程存储查看值