文章目录
一、线程是什么
1.定义
线程是操作系统能够进行运算调度的最小单位。它被包含在进程中,是进程中的实际运作单位。
单核CPU下,线程的执行逻辑
2.为什么会有线程
1.在多核CPU中,利用多线程可以实现真正意义上的并行执行。
2.在一个应用进程中,会存在多个同时执行的任务,如果其中一个任务倍阻塞,将会引起不依赖该任务的任务也被阻塞。通过对不同任务创建不同的线程去处理,可以提升程序处理的实时性。
3.线程可以认为是轻量级的进程,所以线程的创建、销毁比进程更快。
二、线程的应用场景
1.使用多线程实现文件下载
2.后台任务:如定时向大量(100W以上)的用户发送邮件
3.异步处理:记录日志
4.多步骤的任务处理,可根据步骤特征选用不同个数和特征的线程来协作处理,多任务的分割,由一个主线程分割给多个线程完成
三、Java中应用多线程
1.Java中只能单继承,如果当前没有继承任何类,可以继承Thread创建线程,如果已经继承了别的类,可以实现Runnable接口来创建线程
2.如果线程有返回值,可以使用Callable接口来实现
1. 继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getName());
}
public static void main(String[] args) {
new MyThread().start();
}
}
2. 实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("当前线程:" + Thread.currentThread().getName());
}
public static void main(String[] args) {
new Thread(new MyRunnable()).start();
}
}
3. 实现Callable接口
public class MyCallable implements Callable<String> {
@Override
public String call() {
return "Hello Callable";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
String result = executorService.submit(new MyCallable()).get();
System.out.println("线程返回值:" + result);
}
}
四、线程的生命周期
Java线程从创建到销毁,可能会经历6个状态
NEW: 初始状态,线程被创建,但是还没有调用start方法
RUNNABLE:运行状态,JAVA线程把操作系统中的就绪和运行两种状态统一称为“运行中”
BLOCKED:阻塞状态,表示线程进入等待状态,也就是线程因为某种原因放弃了CPU使用权,阻塞也分为几种情况
WAITING:等待状态
TIME_WAITING:超时等待状态,超市以后自动返回
TERMINATED:终止状态,表示当前线程执行完毕
1. 超时等待
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "TIMED_WAITING").start();
2. 等待
new Thread(()->{
try {
ThreadTest.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "WAITING").start();
3. 阻塞
public class ThreadTest {
public static void main(String[] args) {
new Thread(new BlockThread(), "TIMED_WAITING").start();
new Thread(new BlockThread(), "BLOCKED").start();
}
public static class BlockThread implements Runnable{
@Override
public void run() {
synchronized (BlockThread.class) {
while (true) {
try {
TimeUnit.SECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}