1、 线程概念
线程被称为轻量级进程,是程序执行的最小单位,它是指在程序执行过程中,能够执行代码的一个执行单位。每个程序程序都至少有一个线程,也即是程序本身。
2、线程状态
Java语言定义了5种线程状态,在任意一个时间点,一个线程只能有且只有其中一个状态。
(1)新建(New):创建后尚未启动的线程处于这种状态
(2)运行(Runable):Runable包括了操作系统线程状态的Running和Ready,也就是处于此状态的线程有可能正在执行,也有可能正在等待着CPU为它分配执行时间。
(3)等待(Wating):处于这种状态的线程不会被分配CPU执行时间。等待状态又分为无限期等待和有限期等待,处于无限期等待的线程需要被其他线程显示地唤醒,没有设置Timeout参数的Object.wait()、没有设置Timeout参数的Thread.join()方法都会使线程进入无限期等待状态;有限期等待状态无须等待被其他线程显示地唤醒,在一定时间之后它们会由系统自动唤醒,Thread.sleep()、设置了Timeout参数的Object.wait()、设置了Timeout参数的Thread.join()方法都会使线程进入有限期等待状态。
(4)阻塞(Blocked):线程被阻塞了,“阻塞状态”与”等待状态“的区别是:”阻塞状态“在等待着获取到一个排他锁,这个时间将在另外一个线程放弃这个锁的时候发生;而”等待状态“则是在等待一段时间或者唤醒动作的发生。在程序等待进入同步区域的时候,线程将进入这种状态。
(5)结束(Terminated):已终止线程的线程状态,线程已经结束执行。
3、创建线程的方式
①继承Thread类
1 public class WebDownloader { 2 //继承Thread类来创建线程 3 public static void main(String[] args) { 4 //设置线程名字 5 Thread.currentThread().setName("main thread"); 6 MyThread myThread = new MyThread(); 7 myThread.setName("子线程:"); 8 //开启线程 9 myThread.start();10 for(int i = 0;i<5;i++){11 System.out.println(Thread.currentThread().getName() + i);12 }13 }14 }15 16 class MyThread extends Thread{17 //重写run()方法18 public void run(){19 for(int i = 0;i < 10; i++){20 System.out.println(Thread.currentThread().getName() + i);21 }22 }23 }
②实现Runnable接口
1 public class Thread_test01 { 2 //实现Runnable接口 3 public static void main(String[] args) { 4 //设置线程名字 5 Thread.currentThread().setName("main thread:"); 6 Thread thread = new Thread(new MyRunnable()); 7 thread.setName("子线程:"); 8 //开启线程 9 thread.start();10 for (int i = 0; i < 5; i++) {11 System.out.println(Thread.currentThread().getName() + i);12 }13 }14 }15 16 class MyRunnable implements Runnable {17 18 @Override19 public void run() {20 for (int i = 0; i < 10; i++) {21 System.out.println(Thread.currentThread().getName() + i);22 }23 }24 }
③实现Callable接口
1 //实现Callable接口 2 public class Thread_test01 { 3 4 public static void main(String[] args) { 5 //执行Callable 方式,需要FutureTask 实现实现,用于接收运算结果 6 FutureTaskfutureTask = new FutureTask (new MyCallable()); 7 new Thread(futureTask).start(); 8 //接收线程运算后的结果 9 try {10 Integer sum = futureTask.get();11 System.out.println(sum);12 } catch (InterruptedException e) {13 e.printStackTrace();14 } catch (ExecutionException e) {15 e.printStackTrace();16 }17 }18 }19 20 class MyCallable implements Callable {21 22 @Override23 public Integer call() throws Exception {24 int sum = 0;25 for (int i = 0; i < 100; i++) {26 sum += i;27 }28 return sum;29 }30 }
④线程池
1 package cn.Thread_demo; 2 import java.util.concurrent.ExecutorService; 3 import java.util.concurrent.Executors; 4 5 //线程池实现 6 public class Thread_test01 { 7 8 public static void main(String[] args) { 9 //创建线程池10 ExecutorService executorService = Executors.newFixedThreadPool(10);11 ThreadPool threadPool = new ThreadPool();12 for(int i =0;i<5;i++){13 //为线程池分配任务14 executorService.submit(threadPool);15 }16 //关闭线程池17 executorService.shutdown();18 }19 }20 21 class ThreadPool implements Runnable {22 23 @Override24 public void run() {25 for(int i = 0 ;i<10;i++){26 System.out.println(Thread.currentThread().getName() + ":" + i);27 }28 }29 }
4、线程终止
1 package cn.Thread_demo; 2 3 /** 4 * @Classname TerminateThread 5 * @Description TODO 6 * @Date 2019-5-10 17:08 7 * @Created by Administrator 8 *9 * 终止线程的方式10 * 1、线程正常执行完毕----》次数11 * 2、外部干涉----》加入标识12 * 不使用stop destroy13 */14 public class TerminateThread implements Runnable {15 //1、加入标识,标记线程体是否可以运行16 private boolean flag;17 private String name;18 19 public TerminateThread(String name) {20 this.name = name;21 }22 23 24 @Override25 public void run() {26 int i = 0;27 // 2、关联标识,ture--->运行 false--->停止28 while (flag) {29 System.out.println(name + "####----" + i++);30 }31 }32 33 // 3、对外提供方法改变标识34 public void terminateThread() {35 this.flag = false;36 }37 38 public static void main(String[] args) {39 TerminateThread tt = new TerminateThread("J罗");40 new Thread(tt).start();41 42 for (int i = 0; i < 44; i++) {43 if (i==33){44 tt.terminateThread();45 System.out.println("Game,over");46 }47 System.out.println("main---"+i);48 }49 }50 }
运行结果图
5、守护线程
* 守护线程:是为用户线程服务的;jvm停止不用等待守护线程执行完毕 * 默认:用户线程。jvm等待用户线程执行完毕才会停止
1 package cn.Thread_demo; 2 3 /** 4 * @Classname DaemonTest 5 * @Description TODO 6 * @Date 2019-5-13 10:59 7 * @Created by Administrator 8 *9 * 守护线程:是为用户线程服务的;jvm停止不用等待守护线程执行完毕10 * 默认:用户线程jvm等待用户线程执行完毕才会停止11 */12 public class DaemonTest {13 public static void main(String[] args) {14 God god = new God();15 You you = new You();16 Thread t= new Thread(god);17 t.setDaemon(true); //将用户线程调整为守护18 t.start();19 new Thread(you).start();20 }21 }22 23 class You extends Thread {24 public void run() {25 for (int i = 0; i < 365 * 100; i++) {26 System.out.println("happy life...");27 }28 System.out.println("ene ene ene!");29 }30 }31 32 class God extends Thread {33 public void run() {34 for (; true; ) {35 System.out.println("bless you...");36 }37 }38 }