「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。
多线程
⭐️多任务
多任务处理是指用户可以在同一时间内运行多个应用程序,每个应用程序被称作一个任务。例如,在编辑或下载邮件的同时可以打印文件。Linux、windows就是支持多任务的操作系统,比起单任务系统它的功能增强了许多。
多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务。通常,每一个任务称为一个线程( thread), 它是线程控制的简称。可以同时运行一个以上线程的程序称为多线程程序(multithreaded)。
多进程与多线程有哪些区别?
本质的区别在于每个进程拥有自己的一整套变量, 而线程则共享数据。
⭐️什么是线程?
线程被称为轻量级进程,是程序执行的最小单位,它是指在程序执行过程中,能够执行代码的一个执行单位。每个程序程序都至少有一个线程,也即是程序本身。
⭐️线程状态
- New (新创建):创建后尚未启动的线程处于这种状态
- Runnable (可运行):Runable包括了操作系统线程状态的Running和Ready,也就是处于此状态的线程有可能正在执行,也有可能正在等待着CPU为它分配执行时间。
- Blocked (被阻塞):处于这种状态的线程不会被分配CPU执行时间。等待状态又分为无限期等待和有限期等待,处于无限期等待的线程需要被其他线程显示地唤醒,没有设置Timeout参数的Object.wait()、没有设置Timeout参数的Thread.join()方法都会使线程进入无限期等待状态;有限期等待状态无须等待被其他线程显示地唤醒,在一定时间之后它们会由系统自动唤醒,Thread.sleep()、设置了Timeout参数的Object.wait()、设置了Timeout参数的Thread.join()方法都会使线程进入有限期等待状态。
- Waiting (等待):线程被阻塞了,“阻塞状态”与”等待状态“的区别是:”阻塞状态“在等待着获取到一个排他锁,这个时间将在另外一个线程放弃这个锁的时候发生;而”等待状态“则是在等待一段时间或者唤醒动作的发生。在程序等待进入同步区域的时候,线程将进入这种状态。
- Timed waiting (计时等待):
- Terminated (被终止):已终止线程的线程状态,线程已经结束执行。
⭐️创建多线程的方式
继承Thread类
``` //继承Thread类来创建线程 public class ThreadTest {
public static void main(String[] args) { //设置线程名字 Thread.currentThread().setName("main thread"); MyThread myThread = new MyThread(); myThread.setName("子线程:"); //开启线程 myThread.start(); for(int i = 0;i<5;i++){ System.out.println(Thread.currentThread().getName() + i); } } }
class MyThread extends Thread{ //重写run()方法 public void run(){ for(int i = 0;i < 10; i++){ System.out.println(Thread.currentThread().getName() + i); } } } ```
实现Runnable接口
//实现Runnable接口 public class RunnableTest { public static void main(String[] args) { //设置线程名字 Thread.currentThread().setName("main thread:"); Thread thread = new Thread(new MyRunnable()); thread.setName("子线程:"); //开启线程 thread.start(); for(int i = 0; i <5;i++){ System.out.println(Thread.currentThread().getName() + i); } } } class MyRunnable implements Runnable { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + i); } } }
实现Callable接口
``` public class CallableTest {
public static void main(String[] args) { //执行Callable 方式,需要FutureTask 实现实现,用于接收运算结果 FutureTask futureTask = new FutureTask (new MyCallable()); new Thread(futureTask).start(); //接收线程运算后的结果 try { Integer sum = futureTask.get(); System.out.println(sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
class MyCallable implements Callable {
@Override public Integer call() throws Exception { int sum = 0; for (int i = 0; i < 100; i++) { sum += i; } return sum; } } ```
线程池
``` //线程池实现 public class ThreadPoolExecutorTest {
public static void main(String[] args) { //创建线程池 ExecutorService executorService = Executors.newFixedThreadPool(10); ThreadPool threadPool = new ThreadPool(); for(int i =0;i<5;i++){ //为线程池分配任务 executorService.submit(threadPool); } //关闭线程池 executorService.shutdown(); } }
class ThreadPool implements Runnable {
@Override public void run() { for(int i = 0 ;i<10;i++){ System.out.println(Thread.currentThread().getName() + ":" + i); } } } ```
\