多线程(一)

it2026-03-10  2

多线程(一)

进程和线程

并行

多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。

并发

通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。

一个程序(进程)可以同时有很多线程,但同一时间点只能执行其中一条线(单核CPU)

多核cpu使用多线程,可以提升运行速度

案例

一天考4科

分着考正常执行一起考来回换着做就是多线程,所以多线程消耗内存空间,也浪费时间

某人的一天:吃饭,取快递,写作业

实现和开启

要让一段代码具备多线程的能力

实现Thread类

public class Eat extends Thread { String name; public Eat(String name) { this.name = name; } @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(name + ":" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }

实现Thread接口

public class Work implements Runnable { String subject; public Work(String subject) { this.subject = subject; } @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(subject + "zuoye:" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }

都是要在run方法中

代码具备并发能力之后,想以多线程的方式开启,不能直接调用,得使用Thread类的start方法,如果是接口实现,就得重新构造一个Thread类的对象,否则就没有start方法了

public class Test { public static void main(String[] args) { Eat e1 = new Eat("e1"); Eat e2 = new Eat("e2"); e1.start(); e2.start(); // Work w1 = new Work("English"); // Work w2 = new Work("math"); // Thread t1 = new Thread(w1); // Thread t2 = new Thread(w2); // t1.start(); // t2.start(); } }

生命周期

1.新建状态

创建线程对象(new Thread()),不可运行start()

2.就绪状态

线程进入线程队列排队,等待CPU服务 获取CPU资源

3.运行状态

自动调用线程对象的run方法run方法正常执行完毕

4.阻塞状态

人为控制,IO阻塞,锁,sleep等IO获取到资源,获得锁,sleep时间到了等

5.死亡状态

不会再继续运行,内存空间也自动销毁,调用stop方法也可以,但是不要去做

各种状态之间,只有运行和就绪是双向的,可以互相转换

线程的创建是最消耗资源的

线程调度

强制运行,join

多线程并发中,让其中一条线程,强制运行,其他的无法运行,必须等待这个线程运行完成后才能继续运行

例如:

主线程先执行5次,t1开启,两条线程并发执行:如果加上join那么,e1执行,就不允许其他的执行,直到e1的run方法全部结束 public class TestJoin { public static void main(String[] args) { try { ThreadA t1 = new ThreadA("t1"); for (int i = 0; i < 10; i++) { if (i == 5) { t1.start(); t1.join(); } Thread.sleep(1000); System.out.println("main" + i); } } catch (InterruptedException e) { e.printStackTrace(); } } static class ThreadA extends Thread { public ThreadA(String name) { super(name); } @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println("这是 : " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }

中断线程:一个线程运行时,另外一个线程可以通过interrupt方法中断其运行状态

public class TestInterrupt implements Runnable{ @Override public void run() { System.out.println("闭关修炼"); try { Thread.sleep(3000); System.out.println("羽化成仙"); } catch (InterruptedException e) { System.out.println("走火入魔"); return; } System.out.println("修炼完毕"); } } public class Test2 { public static void main(String[] args) { TestInterrupt t = new TestInterrupt(); Thread tt = new Thread(t); tt.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } tt.interrupt(); } }

线程的礼让:使用yield方法将一个线程的操作暂时终止让给其他线程

public class TestYield { public static void main(String[] args) { new Thread(()->{ for(int i=0; i<100; i++) { System.out.println("lambda....."+i); } }).start(); for(int i=1; i<=100; i++) { if(i%20 == 0){ Thread.yield();//main线程礼让 } System.out.println("main...."+i); } } }
最新回复(0)