Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java之线程,常用方法,线程同步,死锁

Java之线程,常用方法,线程同步,死锁

作者头像
二十三年蝉
发布于 2018-02-27 10:45:19
发布于 2018-02-27 10:45:19
1.2K00
代码可运行
举报
文章被收录于专栏:闻道于事闻道于事
运行总次数:0
代码可运行

1, 线程的概念

进程与线程

进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)

线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)

切换而不是同步 一个程序中的方法有几条执行路径, 就有几个线程

Java中线程的生命周期

Java线程具有五中基本状态

新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就     绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

2, 线程的创建:

Thread类:

java.lang Class Thread

  • java.lang.Object
    • java.lang.Thread
  • All Implemented Interfaces:Runnable已知直接子类:ForkJoinWorkerThread

线程是程序中执行的线程。 Java虚拟机允许应用程序同时执行多个执行线程。 每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行。 每个线程可能也可能不会被标记为守护程序。 当在某个线程中运行的代码创建一个新的Thread对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护线程。 创建一个新的执行线程有两种方法。 一个是将一个类声明为Thread的子类。 这个子类应该重写run类的方法Thread 。 另一种方法来创建一个线程是声明实现类Runnable接口。 那个类然后实现了run方法。 然后可以分配类的实例,在创建Thread时作为参数传递,并启动。

两种方式: 1, 继承Thread类 class TestThread extends Thread {......}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package com.hanqi.maya.test;
 2 
 3 import javax.swing.plaf.FontUIResource;
 4 import javax.swing.text.StyledEditorKit.ForegroundAction;
 5 
 6 public class Threadtest {
 7     public static void main(String[] args) {
 8         MyThread mt=new MyThread();
 9         mt.start();//开启线程 
10         for(int i=0;i<50;i++){
11             System.out.println("main"+i);
12         }
13     }
14 }
15 class MyThread extends Thread{ //通过继承Thread类的方法来创建多线程
16     
17     public void run(){
18         for(int i=0;i<50;i++){
19             System.out.println("MyThead"+i);
20         }
21     }
22     
23 }

2, 实现Runnable接口, 然后作为参数传入到Thread类的构造方法中 class TestThread implements Runnable {......}

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package com.hanqi.maya.test;
 2 
 3 import javax.swing.plaf.FontUIResource;
 4 import javax.swing.text.StyledEditorKit.ForegroundAction;
 5 
 6 public class Threadtest {
 7     public static void main(String[] args) {
 8         MyThread mt=new MyThread();
 9         
10         Thread t=new Thread(mt);
11         t.start();//自动去找t中实现的Runnable方法
12         for(int i=0;i<50;i++){
13             System.out.println("main"+i);
14         }
15 /*        
16         mt.start();//开启线程 
17         for(int i=0;i<50;i++){
18             System.out.println("main"+i);
19         }*/
20     }
21 }
22 
23 class MyThread implements Runnable{ //通过继承Thread类的方法来创建多线程
24     
25     public void run(){
26         for(int i=0;i<50;i++){
27             System.out.println("MyThead"+i);
28         }
29     }
30     
31 }
32 /*class MyThread extends Thread{ //通过继承Thread类的方法来创建多线程
33     
34     public void run(){
35         for(int i=0;i<50;i++){
36             System.out.println("MyThead"+i);
37         }
38     }
39     
40 }*/

线程的启动:

调用线程类中的start()方法, 不能直接调用run()方法, 直接调用run()方法是方法调用, 不是启动线程

3, 线程常用方法

isAlive() 判断线程是否还活着, 调用start()之前和终止之后都是死的, 其他的都是活的

判断线程是否还在

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package com.hanqi.maya.test;
 2 
 3 public class TestThread1 {
 4     public static void main(String[] args) {
 5         MyThread1 mt=new MyThread1();
 6         
 7         Thread t=new Thread(mt);
 8         
 9         System.out.println(t.isAlive());//判断线程是否还在,此处线程未开启
10         t.start();
11         System.out.println(t.isAlive());//判断线程是否还在,此处线程已经开启
12     }
13 }
14 
15 class MyThread1 implements Runnable{ //通过继承Thread类的方法来创建多线程
16     
17     public void run(){
18         for(int i=0;i<50;i++){
19             System.out.println("MyThead"+i);
20         }
21     }
22 }

优先级

getPriority() setPriority() 设置优先级, 优先级的概念: 谁的优先级高, 谁执行的时间就多 Thread里面的默认优先级: Thread.MIN_PRIORITY = 1 Thread.MAX_PRIORITY = 10 Thread.NORM_PRIORITY = 5

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package com.hanqi.maya.test;
 2 
 3 public class TestPriority {
 4     public static void main(String[] args) {
 5         MyThread11 mt1 = new MyThread11("超人");
 6         MyThread2 mt2 = new MyThread2("蝙蝠侠");
 7         mt1.setPriority(Thread.NORM_PRIORITY + 5);//设置优先级
 8         mt1.start();
 9         mt2.start();
10         System.out.println("123");
11         try {
12             Thread.sleep(2000);
13         } catch (InterruptedException e) {
14             // TODO Auto-generated catch block
15             e.printStackTrace();
16         }
17         System.out.println(456);
18     }
19 }
20 
21 
22 class MyThread11 extends Thread {
23     
24     public MyThread11(String name) {
25         super(name);//调用父类构造方法将name穿减去
26     }
27 
28     public void run() {
29         for (int i = 0; i < 50; i++) {
30             System.out.println(this.getName() + ": " + i);
31         }
32     }
33 }
34 
35 class MyThread2 extends Thread {
36     
37     public MyThread2(String name) {
38         super(name);
39     }
40     
41     public void run() {
42         for (int i = 0; i < 50; i++) {
43             System.out.println(this.getName() + ": " + i);
44         }
45     }
46 }

沉睡和终止

interrupt() 停止线程

这个方法要配合延迟使用,不要直接启动线程然后直接使用此方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package interupt;
 2 
 3 import java.util.Date;
 4 
 5 public class TestInterupt {
 6     public static void main(String[] args) {
 7         MyNewThread mnt = new MyNewThread();
 8         Thread t = new Thread(mnt);
 9         t.start();
10         try {
11             Thread.sleep(5000);
12         } catch (InterruptedException e) {
13             e.printStackTrace();
14         }
15         t.interrupt();
16         t.stop();
17 //         终止线程, 将run方法结束, 线程就结束了
18         MyNewThread.flag = false;
19     }
20 }
21 
22 class MyNewThread implements Runnable {
23 
24     static boolean flag = true;
25     @Override
26     public void run() {
27         while(flag) {
28             System.out.println(new Date());
29             try {
30                 Thread.sleep(1000);
31             } catch (Exception e) {
32                 System.out.println("线程终止 !");
33                 System.out.println(e.getMessage());
34                 return;
35             }
36         }
37     }
38     
39 }

Thread.sleep(long millions)将程序暂停一会,暂停当前线程,如果没有线程也可以给普通程序暂停,需要抛出一个异常即可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package com.hanqi.maya.test;
 2 
 3 import java.util.Date;
 4 
 5 public class TestInterupt {
 6     public static void main(String[] args) {
 7         MyNewThread mnt = new MyNewThread();
 8         Thread t = new Thread(mnt);
 9         t.start();
10         try {
11             Thread.sleep(5000);//先沉睡5s
12         } catch (InterruptedException e) {
13             e.printStackTrace();
14         }
15         /*t.interrupt();//调用会抛出异常
16         t.stop();//不建议使用,已经过时
17 *///         终止线程, 将run方法结束, 线程就结束了
18         MyNewThread.flag = false;//更改属性终止线程
19     }
20 }
21 
22 class MyNewThread implements Runnable {
23 
24     static boolean flag = true;
25     @Override
26     public void run() {
27         while(flag) {
28             System.out.println(new Date());
29             try {
30                 Thread.sleep(1000);//延迟一秒
31             } catch (Exception e) {
32                 System.out.println("线程终止 !");
33                 System.out.println(e.getMessage());
34                 return;
35             }
36         }
37     }
38     
39 }

 join() 合并线程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package join;
 2 
 3 public class TestJoin {
 4     public static void main(String[] args) {
 5         NewThread nt = new NewThread();
 6         nt.start();
 7         try {
 8             nt.join();//合并线程,继承自Thread,将这个线程加到当前线程,先执行这个线程
 9         } catch (InterruptedException e) {
10             e.printStackTrace();
11         }
12         
13         for (int i = 0; i < 10; i++) {
14             System.out.println("我是main线程-----" + i);
15         }
16     }
17 }
18 
19 class NewThread extends Thread {
20     public void run() {
21         for (int i = 0; i < 10; i++) {
22             System.out.println("我是NewThread线程=====" + i);
23         }
24     }
25 }

yield()---礼让 让出CPU执行其他线程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package com.hanqi.maya.test;
 2 
 3 public class TestPriority {
 4     public static void main(String[] args) {
 5         MyThread11 mt1 = new MyThread11("超人");
 6         MyThread2 mt2 = new MyThread2("蝙蝠侠");
 7         mt1.setPriority(Thread.NORM_PRIORITY + 5);//设置优先级
 8         mt1.start();
 9         mt2.start();
10         System.out.println("123");
11         try {
12             Thread.sleep(2000);
13         } catch (InterruptedException e) {
14             // TODO Auto-generated catch block
15             e.printStackTrace();
16         }
17         System.out.println(456);
18     }
19 }
20 
21 
22 class MyThread11 extends Thread {
23     
24     public MyThread11(String name) {
25         super(name);//调用父类构造方法将name穿减去
26     }
27 
28     public void run() {
29         for (int i = 0; i < 50; i++) {
30             System.out.println(this.getName() + ": " + i);
31         }
32     }
33 }
34 
35 class MyThread2 extends Thread {
36     
37     public MyThread2(String name) {
38         super(name);
39     }
40     
41     public void run() {
42         for (int i = 0; i < 50; i++) {
43             System.out.println(this.getName() + ": " + i);
44         }
45     }
46 }

wait()

  • 导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或指定的时间已过。

notify()

  • public final void notify() 唤醒正在等待对象监视器的单个线程。 如果任何线程正在等待这个对象,其中一个被选择被唤醒。 选择是任意的,并且由实施的判断发生。 线程通过调用wait方法之一等待对象的监视器。 唤醒的线程将无法继续,直到当前线程放弃此对象上的锁定为止。 唤醒的线程将以通常的方式与任何其他线程竞争,这些线程可能正在积极地竞争在该对象上进行同步; 例如,唤醒的线程在下一个锁定该对象的线程中没有可靠的权限或缺点。

notifyAll()---

  • public final void notifyAll() 唤醒正在等待对象监视器的所有线程。 线程通过调用wait方法之一等待对象的监视器。 唤醒的线程将无法继续,直到当前线程释放该对象上的锁。 唤醒的线程将以通常的方式与任何其他线程竞争,这些线程可能正在积极地竞争在该对象上进行同步; 例如,唤醒的线程在下一个锁定该对象的线程中不会有可靠的特权或缺点。

4, 线程同步 synchronized

线程的同步是保证多线程安全访问竞争资源的一种手段。

当多个线程同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到的执行。 

线程同步的真实意思和字面意思恰好相反。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。

比如银行取钱:

银行卡余额3000,A从取款机取2000,B也想从支付宝这张卡转出2000,这时就要用到线程同步

线程同步,可以在方法声明中用 synchronized 关键字

也可以用 synchronized 关键字将代码块包起来实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package com.hanqi.util;
 2 
 3 public class Bank {
 4     public int money=3000;
 5     
 6     public /*synchronized*/ void getMoney(String name,int mon){
 7         synchronized(this){
 8             if(money>mon&&money>0){
 9                 try {
10                     Thread.sleep(1);
11                 } catch (InterruptedException e) {
12                     e.printStackTrace();
13                 }
14                 
15                 money-=mon;
16                 System.out.println("hi,"+name);
17                 System.out.println("取款"+mon);
18                 System.out.println("余额:"+money);
19                 
20             }else{
21                 System.out.println("hi,"+name);
22                 System.out.println("取款失败");
23                 System.out.println("余额:"+money);
24             }
25         }
26     }
27 }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package com.hanqi.util;
 2 
 3 public class Threadt1 {
 4 
 5     public static void main(String[] args) {
 6         MyThread mt=new MyThread();
 7         
 8         Thread t1=new Thread(mt);
 9         Thread t2=new Thread(mt);
10         
11         t1.setName("Tom");
12         t2.setName("BomSa");
13         
14         t1.start();
15         t2.start();
16     }
17 }
18 class MyThread implements Runnable{
19     public Bank bank=new Bank();
20     @Override
21     public void run() {
22         bank.getMoney(Thread.currentThread().getName(), 2000);
23     }
24 }

五、死锁概念

所谓死锁,是两个甚至多个线程被永久阻塞时的一种运行局面,这种局面的生成伴随着至少两个线程和两个或者多个资源。两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 package com.hanqi.util;
 2 
 3 public class Deadlock implements Runnable {
 4 
 5     
 6     public static void main(String[] args) {
 7         
 8         Deadlock d1 = new Deadlock();
 9         Deadlock d2 = new Deadlock();
10         
11         d1.flag = 1;
12         d2.flag = 2;
13         
14         Thread t1 = new Thread(d1);
15         Thread t2 = new Thread(d2);
16         
17         t1.start();
18         t2.start();
19         
20     }
21     
22     public static Object obj1 = new Object();
23     public static Object obj2 = new Object();
24 
25     public int flag;
26 
27     @Override
28     public void run() {
29         if (flag == 1) {
30             System.out.println("这是第" + flag + "个线程");
31             synchronized (obj1) {
32                 try {
33                     Thread.sleep(500);
34                 } catch (InterruptedException e) {
35                     e.printStackTrace();
36                 }
37                 synchronized (obj2) {
38                     System.out.println("第" + flag + "个线程结束");
39                 }
40             }
41         }
42         
43         if (flag == 2) {
44             System.out.println("这是第" + flag + "个线程");
45             synchronized (obj2) {
46                 try {
47                     Thread.sleep(500);
48                 } catch (InterruptedException e) {
49                     e.printStackTrace();
50                 }
51                 synchronized (obj1) {
52                     System.out.println("第" + flag + "个线程结束");
53                 }
54             }
55         }
56 
57     }
58 
59 }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-08-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
第二十五天 多线程-常用方法&线程池【悟空教程】
System.out.println(getName() + " ==== " + i );
Java帮帮
2018/07/26
3910
第二十五天 多线程-常用方法&线程池【悟空教程】
day18-多线程&线程同步&死锁
在操作系统中,安装了多个程序,并发指的是在一段时间内宏观上有多个程序同时运行,这在单 CPU 系统中,每一时刻只能有一道程序执行,即微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那是因为分时交替运行的时间是非常短的。
张哥编程
2024/12/13
930
菜鸟说: 线程那点事(java篇)
多线程编程除了在现实工作中经常会被应用到,而且在面试的时候不少的面试官也喜欢问这些多线程的东西来作为他们考量一个面试者基础水平的标准.可见它存在的实用性,那么我觉得作为一个程序员学习者来说,当然得好好学一学,本随笔将会从我自己的角度讲一下我个人对多线程的理解以及应用。
用户7886150
2020/12/11
3850
控制线程
线程状态转换 线程控制基本方法 方法 功能 isAlive() 判断线程是否终止 getpriority() 获得线程的优先级数值 setpriority() 设置线程优先级数值 Thread.sle
mathor
2018/07/04
3640
Java 线程基础
简言之,进程可视为一个正在运行的程序。它是系统运行程序的基本单位,因此进程是动态的。进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动。进程是操作系统进行资源分配的基本单位。
静默虚空
2019/12/26
4890
Java 线程基础
【day17】多线程基础
进程是在内存中执行的应用程序,而线程是进程中最小的执行单元,负责当前进程中程序的运行。一个进程中至少有一个线程,多个线程的应用程序称为多线程程序。
程序员波特
2024/12/26
900
【day17】多线程基础
Java:认识多线程
概述 什么是线程??? 进程的概念:进程是指可执行程序并存放在计算机存储器的一个指令序列,他是一个动态执行的过程。 进程的概念和特征_C语言中文网 (biancheng.net) 线程是比进程还要小的运行单位,一个进程含多个线程 Thread类和Runnable接口介绍 线程创建 创建一个Thread类,或者一个Thread子类的对象 创建一个实现Runnable接口的类的对象 Thread类 Thread是一个线程类,位于java.lang包下 Thread类的常用方法 Runnable接口 只有
Breeze.
2022/06/05
2350
Java:认识多线程
Java之多线程-------入门
是指从软件或者硬件上实现多个线程并发执行的技术。 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能。
楠羽
2022/11/18
3790
Java之多线程-------入门
Java多线程
1.新建:程序使用new创建线程后,就是新建状态,jvm会为他分配内存,并初始化成员变量的值
用户11010370
2024/03/08
1290
十五、多线程【黑马JavaSE笔记】
假如计算机只有一个CPU,那么CPU在某一个时刻只能执行一条指令,线程只有得到CPU时间片,也就是使用权,才可以执行指令。所以说多线程程序的执行是有随机性,因为谁抢到CPU的使用权是不一定的
啵啵鱼
2022/11/23
2920
十五、多线程【黑马JavaSE笔记】
Java线程知识点总结
简言之,进程可视为一个正在运行的程序。它是系统运行程序的基本单位,因此进程是动态的。进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动。进程是操作系统进行资源分配的基本单位。
鱼找水需要时间
2023/03/09
3060
Java线程知识点总结
Java多线程(一篇从0讲透)
进程:是指一个内存中运行的程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程
不吃紫菜
2023/04/02
3960
Java多线程(一篇从0讲透)
深入理解多线程
多线程是java中比较重要的一部分内容,使用多线程有许多的优点: - 提高应用程序的响应。对图形化界面更有意义,可增强用户体验。 - 程序需要实现一些需要等待的任务时,可以提高计算机系统CPU的利用率 - 改善程序结构。将既长又复杂的进程分为多个线程,独立运行,利于理解和修改
栋先生
2018/09/29
7240
深入理解多线程
多线程(一):创建线程和线程的常用方法
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
全栈程序员站长
2022/08/11
1.1K0
多线程(一):创建线程和线程的常用方法
java线程详解(史上最全)
根据本人多年从业以及学习经验,录制了一套最新的Java精讲视频教程,如果你现在也在学习Java,在入门学习Java的过程当中缺乏系统的学习教程,你可以加QQ群654631948领取下学习资料,面试题,开发工具等,群里有资深java老师做答疑,每天也会有基础部分及架构的直播课,也可以加我的微信renlliang2013做深入沟通,只要是真心想学习Java的人都欢迎。
全栈程序员站长
2022/09/08
2740
java线程详解(史上最全)
Java多线程技能
本文介绍了线程的用法,包括线程的创建、启动、挂起、结束等操作,并讲解了线程的共享资源、线程的同步、线程的中断等概念。同时,本文还介绍了线程的优先级、线程的状态、线程的同步、线程的通信、线程的调度、线程的同步等问题。
Java后端工程师
2017/12/13
1.1K0
Java 线程的六种状态
进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。
Jacob丶
2020/08/05
5440
Java 线程的六种状态
Java多线程学习(一)Java多线程入门
Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Java_Guide
用户2164320
2018/06/17
2.2K0
多线程基础
例子:单核CUP执行两件事,串行执行时间快,还是多线程执行快? 答:串行执行快。因为单核,执行的总时间一样,而多线程增加了线程切换的时间。
冬天vs不冷
2025/01/20
1000
多线程基础
Java多线程Thread VS Runnable详解
本文讲述如何使用Java多线程技术实现一个安全的卖票程序,通过分析线程的生命周期、线程的分类以及线程安全问题,结合实际案例讲解了如何在实际项目中应用多线程技术。
Java后端工程师
2017/12/15
1.1K0
相关推荐
第二十五天 多线程-常用方法&线程池【悟空教程】
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验