news 2026/4/22 3:14:33

Java多线程入门:创建与结束线程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java多线程入门:创建与结束线程

第十七章:多线程

常见概念

进程和线程

进程:运行中的程序

线程:线程是由进程创建的,是进程的一个实体,当然线程也可以由线程创建,如:一个线程创建一个子线程

单线程和多线程

单线程:同一个时刻,只允许执行一个线程 多线程:同一个时刻,可以执行多个线程

并发和并行

并发:同一个时刻,多个任务交替执行(单核来回切换) 并行:同一个时刻,多个任务同时执行。多核CPU可以实现并行 并发和并行可以同时存在:并行中又包含并发

同步进而实现互斥

线程 / 进程的同步和互斥:

  • 同步:协调多个并发实体执行的顺序 —进而实现—>互斥:控制多个并发实体不能同时访问同一个资源,即要上锁

多线程

创建线程⭐

实现Runnable接口,重写run方法:

packagecom.lcz.mutithread.create;/** * @author lcz * @version 1.0 */publicclassThread02{publicstaticvoidmain(String[]args){Dogdog=newDog();Threadthread=newThread(dog);thread.start();}}classDogimplementsRunnable{privateintcount=0;@Overridepublicvoidrun(){while(true){System.out.println("小狗汪汪汪叫..."+(++count));try{Thread.sleep(1000);}catch(InterruptedExceptione){thrownewRuntimeException(e);}if(count==8){break;}}}}

结束线程⭐

  1. 自动结束:线程完成任务后,自动结束
  2. 通知结束:使用布尔变量来控制任务的结束,进而线程结束
packagecom.lcz.mutithread.exit;/** * @author lcz * @version 1.0 */publicclassExit01{publicstaticvoidmain(String[]args){Dogdog=newDog();Threadthread=newThread(dog);thread.start();try{Thread.sleep(10*1000);//主线程休眠10秒}catch(InterruptedExceptione){thrownewRuntimeException(e);}dog.setLoop(false);//通知退出子线程}}classDogimplementsRunnable{privateintcount=0;privatebooleanloop=true;publicvoidsetLoop(booleanloop){this.loop=loop;}@Overridepublicvoidrun(){while(loop){System.out.println("小狗汪汪汪叫..."+(++count));try{Thread.sleep(1000);}catch(InterruptedExceptione){thrownewRuntimeException(e);}if(count==80){break;}}}}

线程常用方法

  • setName
  • getName
  • setPriority
  • getPriority
  • sleep:静态方法
  • interrupt
  • yield(静态方法):线程的礼让,让出cpu,让其他线程执行,但不一定成功(取决于内核态资源是否紧张)
  • join:线程的插队。插队的线程一旦插队成功,则肯定先执行完插入的线程所有的任务
细节
1.线程优先级的范围: MAX_PRIORITY:10MIN_PRIORITY:1NORM_PRIORITY:52.interrupt,中断线程,但并没有真正的结束线程,所以一般用于中断正在休眠线程3.sleep:使当前线程休眠
代码演示
packagecom.lcz.mutithread.method;/** * @author lcz * @version 1.0 * 线程常用方法使用 */publicclassMethod{publicstaticvoidmain(String[]args){Dogdog=newDog();Threadthread=newThread(dog);thread.setName("lcz");thread.setPriority(Thread.NORM_PRIORITY);thread.start();for(inti=0;i<5;i++){System.out.println("主线程:"+i+",线程名字:"+thread.getName()+",线程优先级:"+thread.getPriority());try{Thread.sleep(1000);}catch(InterruptedExceptione){thrownewRuntimeException();}}thread.interrupt();//中断thread线程休眠}}classDogimplementsRunnable{privateintcount=0;@Overridepublicvoidrun(){while(true){System.out.println("小狗汪汪汪叫..."+(++count));try{Thread.sleep(20000);}catch(InterruptedExceptione){}if(count==50)break;}}}
packagecom.lcz.mutithread.method;/** * @author lcz * @version 1.0 * 线程常用方法:yield和join */publicclassMethod01{publicstaticvoidmain(String[]args)throwsInterruptedException{Tt=newT();Threadthread=newThread(t);thread.start();for(inti=0;i<20;i++){System.out.println("主线程(小弟)吃包子"+i);Thread.sleep(1000);if(i==5){//thread.join();//子线程插队Thread.yield();}}}}classTimplementsRunnable{privateintcount=0;@Overridepublicvoidrun(){while(true){System.out.println("子线程(老大)吃包子 "+(++count));try{Thread.sleep(1000);}catch(InterruptedExceptione){thrownewRuntimeException(e);}if(count==20)break;}}}

用户线程和守护线程

  1. 用户线程:也叫工作线程,当线程的任务执行完或通知方式来结束
  2. 守护线程:一般是为工作线程服务的,当所有的用户线程结束,守护线程自动结束
    1. 常见的守护线程:垃圾回收机制
    2. thread.setDaemon(true); //将子线程设置为守护线程,会随着用户线程(工作线程)结束而自动结束
packagecom.lcz.mutithread.method;/** * @author lcz * @version 1.0 */publicclassMyDaemonThread{publicstaticvoidmain(String[]args)throwsInterruptedException{Aa=newA();Threadthread=newThread(a);thread.setDaemon(true);//将子线程设置为守护线程,会随着用户线程(工作线程)结束而自动结束//守护线程作用:用于检测其他线程信息thread.start();for(inti=0;i<10;i++){System.out.println("框框学习..."+i);Thread.sleep(500);}}}classAimplementsRunnable{@Overridepublicvoidrun(){while(true){for(inti=0;i<10;i++){System.out.println("嗷嗷难受..."+i);try{Thread.sleep(500);}catch(InterruptedExceptione){thrownewRuntimeException(e);}}}}}

线程状态⭐

线程生命周期:

1.new:创建状态 2.Runnable:可运行状态 (1):Ready:就绪状态 (2):Running:运行状态 4.waiting:等待状态,等待某些资源 5.Blocked:阻塞状态,等待互斥锁 6.Terminated:终止状态

线程同步互斥机制⭐

synchronized 关键字声明方法为同步方法 / 代码块为同步代码块,即仅能一个线程访问,访问时会为这个方法上一个互斥锁,进而实现线程互斥

同步的局限性:导致程序的执行效率降低

publicsynchronizedvoidm(Stringname){//需要被同步的代码}synchronized(this){//使用 this 对象互斥锁,保证任一时刻,只能有一个线程访问该对象//同步代码块:得到对象互斥锁的线程才可执行同步代码块}
解决超卖问题
packagecom.lcz.mutithread.syn_;/** * @author lcz * @version 1.0 */publicclassSellTicket01extendsThread{privatestaticintcount=100;publicsynchronizedstaticvoidsell(){//将静态方法声明为同步方法,锁为当前类 SellTicket01.class//表示只有获得该锁,才可执行下方同步代码while(true){if(count<=0)break;try{Thread.sleep(50);}catch(InterruptedExceptione){thrownewRuntimeException(e);}System.out.println("售票一张,剩余票数:"+(--count));}}@Overridepublicvoidrun(){sell();}publicstaticvoidmain(String[]args){//不会出现超卖现象,因为使用线程同步机制实现线程互斥SellTicket01sellTicket01=newSellTicket01();SellTicket01sellTicket02=newSellTicket01();SellTicket01sellTicket03=newSellTicket01();sellTicket01.start();sellTicket02.start();sellTicket03.start();}}

死锁现象⭐

两个线程相互占有对方资源,而想要获取对方已占有资源,但无法获得对方资源就无法释放自身资源的情况!编写程序要避免。

packagecom.lcz.mutithread.syn_;/** * @author lcz * @version 1.0 */publicclassDeadLock{publicstaticvoidmain(String[]args){MyDeadLockDemomyDeadLockDemo=newMyDeadLockDemo(true);ThreadA=newThread(myDeadLockDemo);A.setName("A线程");MyDeadLockDemomyDeadLockDemo1=newMyDeadLockDemo(false);ThreadB=newThread(myDeadLockDemo1);B.setName("B线程");A.start();B.start();}}classMyDeadLockDemoimplementsRunnable{privatebooleanflag;privatestaticObjecto1=newObject();privatestaticObjecto2=newObject();publicMyDeadLockDemo(booleanflag){this.flag=flag;}@Overridepublicvoidrun(){if(flag){synchronized(o1){System.out.println("当前线程: "+Thread.currentThread().getName());synchronized(o2){System.out.println("当前线程: "+Thread.currentThread().getName());}}}else{synchronized(o2){System.out.println("当前线程: "+Thread.currentThread().getName());synchronized(o1){System.out.println("当前线程: "+Thread.currentThread().getName());}}}}}
是否释放锁的几种情况

会释放锁:

  • 线程进入等待状态(等待某些资源),会释放锁

不会释放锁:

  • sleep()和 yield()方法,不会释放锁

更多编程学习资源

编程学习公众号【程序员论周】

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 13:30:29

数据库开发环境搭建终极指南:从零开始快速上手

数据库开发环境搭建终极指南&#xff1a;从零开始快速上手 【免费下载链接】beekeeper-studio beekeeper-studio/beekeeper-studio: Beekeeper Studio 是一款开源的跨平台数据库客户端工具&#xff0c;支持多种数据库&#xff08;如MySQL, PostgreSQL, SQLite等&#xff09;&am…

作者头像 李华
网站建设 2026/4/22 10:08:43

Apache DataFusion终极指南:5步构建高性能SQL查询引擎 [特殊字符]

Apache DataFusion终极指南&#xff1a;5步构建高性能SQL查询引擎 &#x1f680; 【免费下载链接】datafusion Apache DataFusion SQL Query Engine 项目地址: https://gitcode.com/gh_mirrors/datafu/datafusion Apache DataFusion是一个基于Rust构建的高性能查询引擎&…

作者头像 李华
网站建设 2026/4/22 7:20:42

没显卡怎么玩Qwen2.5?云端GPU镜像2块钱体验极速对话

没显卡怎么玩Qwen2.5&#xff1f;云端GPU镜像2块钱体验极速对话 你是不是也遇到过这样的情况&#xff1a;产品经理想测试一个大模型能不能用在客服系统里&#xff0c;结果IT说申请服务器要走两周流程&#xff0c;等不起&#xff1b;公司又没有现成的GPU资源&#xff0c;本地电…

作者头像 李华
网站建设 2026/4/22 12:14:21

RPCS3模拟器汉化速成手册:三招告别语言障碍的实用技巧

RPCS3模拟器汉化速成手册&#xff1a;三招告别语言障碍的实用技巧 【免费下载链接】rpcs3 PS3 emulator/debugger 项目地址: https://gitcode.com/GitHub_Trending/rp/rpcs3 还在为PS3游戏里的日文英文发愁吗&#xff1f;别担心&#xff0c;今天咱们就来聊聊怎么用RPCS3…

作者头像 李华
网站建设 2026/4/19 17:13:34

打破技术壁垒:AI机械臂控制系统从零到精通实战指南

打破技术壁垒&#xff1a;AI机械臂控制系统从零到精通实战指南 【免费下载链接】openpi 项目地址: https://gitcode.com/GitHub_Trending/op/openpi 还记得第一次面对机械臂控制代码时的迷茫吗&#xff1f;硬件驱动复杂、环境配置冲突、算法实现困难...这些问题是否曾让…

作者头像 李华
网站建设 2026/4/16 11:50:02

Frigate NVR终极指南:打造专业级本地AI监控系统

Frigate NVR终极指南&#xff1a;打造专业级本地AI监控系统 【免费下载链接】frigate NVR with realtime local object detection for IP cameras 项目地址: https://gitcode.com/GitHub_Trending/fr/frigate Frigate NVR是一款专为智能家居设计的开源网络视频录像系统&…

作者头像 李华