线程:程序运行的最小单位。
进程:一个具有独立功能的程序关于某个数据集合的一次运行活动。
进程是程序的实体。
进程由多个线程组成。
线程的生命周期:新建,就绪,运行,阻塞以及死亡。
多线程的应用场景:程序中出现需要等待的操作。
程序中出现可分解的大任务。
程序中出现需要后台运行的任务。
线程的实现方式
package com.thread; //通过继承Thread类实现自定义线程类 public class MyThread extends Thread { //线程体 @Override public void run() { System.out.println("Hello, I am the defined thread created by extends Thread"); } public static void main(String[] args){ //实例化自定义线程类实例 Thread thread = new MyThread(); //调用start()实例方法启动线程 thread.start(); } }
优点:实现简单,只需实例化继承类的实例,即可使用线程
缺点:扩展性不足,Java是单继承的语言,如果一个类已经继承了其他类,就无法通过这种方式实现自定义线程。
方式二:实现Runnable接口
package com.thread; public class MyRunnable implements Runnable { //线程体 @Override public void run() { System.out.println("Hello, I am the defined thread created by implements Runnable"); } public static void main(String[] args){ //线程的执行目标对象 MyRunnable myRunnable = new MyRunnable(); //实际的线程对象 Thread thread = new Thread(myRunnable); //启动线程 thread.start(); } }
优点:
-
扩展性好,可以在此基础上继承其他类,实现其他必需的功能
-
对于多线程共享资源的场景,具有天然的支持,适用于多线程处理一份资源的场景
缺点:构造线程实例的过程相对繁琐一点
方式三:实现Callable接口
package com.thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class MyCallable implements Callable<String> { @Override public String call() throws Exception { return "Hello, I am the defined thread created by implements Callable"; } public static void main(String[] args){ //线程执行目标 MyCallable myCallable = new MyCallable(); //包装线程执行目标,因为Thread的构造函数只能接受Runnable接口的实现类,而FutureTask类实现了Runnable接口 FutureTask<String> futureTask = new FutureTask<>(myCallable); //传入线程执行目标,实例化线程对象 Thread thread = new Thread(futureTask); //启动线程 thread.start(); String result = null; try { //获取线程执行结果 result = futureTask.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println(result); } }
优点:
- 扩展性好
- 支持多线程处理同一份资源
- 具备返回值以及可以抛出受检查异常
缺点:
- 相较于实现Runnable接口的方式,较为繁琐