线程的基本概念
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。
——百度百科
线程的转换状态
线程的创建
线程的创建有两种方法,一种是implements自Runnable接口,一种是扩展自Thread类,两者均需要实现run方法。当线程对象被new出来时,线程进入到初始状态,当线程执行了start方法时,线程进入到可运行状态(很短,很快进入到执行状态)。
Runnable接口
1 package base.newthread; 2 3 public class Thread2 extends Thread { 4 5 @Override 6 public void run() { 7 System.out.println(Thread.currentThread().getName()); 8 } 9 10 }
1 package base.newthread; 2 3 public class Main { 4 public static void main(String[] args) { 5 6 Thread1 runnable1 = new Thread1(); 7 Thread t1 = new Thread(runnable1, "t1");//线程进入初始状态 8 t1.start(); //线程进入到就绪状态 9 10 Thread2 t2 = new Thread2(); //线程进入初始状态11 t2.setName("t2");12 t2.start(); //线程进入到就绪状态13 }14 }
线程的让出
进程在执行状态时,时间片被用完或主动执行了yield方法,则该进程会释放执行态资源进入到可运行状态等待被重新调度。下面的例子大体可以看出调用yield与不调用yield方法的区别。
1 package base.yield; 2 3 public class Thread1 implements Runnable{ 4 5 @Override 6 public void run() { 7 for (int i = 0; i < 100; i++) { 8 System.out.println(Thread.currentThread().getName() + ":" + i); 9 //Thread.yield();10 }11 }12 }
1 package base.yield; 2 3 public class Thread2 extends Thread { 4 5 @Override 6 public void run() { 7 for (int i = 0; i < 100; i++) { 8 System.out.println(Thread.currentThread().getName() + ":" + i); 9 //Thread.yield();10 }11 }12 13 }
1 package base.yield; 2 3 public class Main { 4 public static void main(String[] args) { 5 6 Thread1 runnable1 = new Thread1(); 7 Thread t1 = new Thread(runnable1, "t1");//线程进入初始状态 8 t1.start(); //线程进入到就绪状态 9 10 Thread2 t2 = new Thread2(); //线程进入初始状态11 t2.setName("t2");12 t2.start(); //线程进入到就绪状态13 }14 }
线程的阻塞
线程进入阻塞有三种分类:
- 调用synchronize进入到锁池状态,当线程获取到锁资源则进入到runnable状态
- 通过调用wait进入到等待队列,待其他进程调用了notify或notifyAll后进入到锁池状态,当线程获取到锁资源则进入到runnable状态
- 通过调用sleep、调用join或是阻塞在等待输入,则进入到阻塞状态;当sleep时间到达或等待的进程执行结束或获取到输入结果后,线程进入到runnable状态。