多线程笔记:多线程基础 - 1
1.线程的创建和启动方式: 1.自定义类,让其继承Thread并重写run()方法,创建此类的对象。调用start()方法启动 public class MyThread extends Thread { //自定义线程类 @Override public void run() { 。。。 } } MyThread t1 = new MyThread(); //创建 t1.start(); //启动 2.自定义类实现runnable接口,实现run()方法,创建Thread对象并传入这个实现类。调用start()方法启动 public class MyThread2 implements Runnable { //实现类 @Override public void run() { 。。。 } } MyRunnable r = new MyRunnable(); Thread t1 = new Thread(r); //创建线程 t1.start(); // 启动 注意:只有Thread对象才有start()方法用于启动线程 2.线程之间数据共享 1.创建runnable实现类或继承Thread,重写run()方法: public class MyRunnable implements Runnable { private int count = 100; //要共享的变量 @Override public void run() { while (count > 0) { try { Thread.sleep(100); count --; System.out.println(count); } catch (InterruptedException e) { e.printStackTrace(); } } } } 2.创建多个线程, MyRunnable r = new MyRunnable(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); t1.start(); t2.start(); 此时t1,t2共享了变量count 注意:这里有线程安全问题 3.Thread的方法: Thread.currentThread() //静态方法,获取当前正在运行线程(执行此代码的线程)对象 isAlive() //检查线程是否处于活动状态,活动状态:线程已经启动且尚未停止 Thread.sleep() //静态方法,让当前线程(执行此代码的线程)休眠 getId() //获取线程的唯一标识 例子: MyRunnable r = new MyRunnable(); Thread t1 = new Thread(r); System.out.println(Thread.currentThread().getName()); System.out.println(Thread.currentThread().getId()); System.out.println(t1.getName()); System.out.println(t1.getId()); Thread.sleep(1000); System.out.println(t1.isAlive()); t1.start(); System.out.println(t1.isAlive()); 运行结果: main 1 Thread-0 11 false true 4.线程的停止 1. interrupt(); 用于停止线程的方法 //做了一件事:将线程停止状态的值置为了true 注意!!这里调用interrupt()方法停止线程,所谓停止线程并不是说线程执行完这个方法后就不执行了。调用此方法 仅仅是改变了线程的状态。线程中有一个标识线程是否停止的状态值。interrupt()方法将此值置为true,线程将继续往下执行。 例子: System.out.println("执行前"); Thread.currentThread().interrupt(); System.out.println("执行后"); 运行结果: 执行前 执行后 //调用interrupt方法后,线程依然在执行 2.查看停止状态的方法: 1. isInterrupted() //用于查看线程状态,返回boolean 例子: System.out.println("执行前"); boolean status1 = Thread.currentThread().isInterrupted(); System.out.println(status1); Thread.currentThread().interrupt(); boolean status2 = Thread.currentThread().isInterrupted(); System.out.println(status2); System.out.println("执行后"); 运行结果: 执行前 false //执行前为false true //执行后为true 执行后 2.interrupted() //也是用于查看线程状态,为静态方法 例子: System.out.println("执行前"); System.out.println(Thread.interrupted()); Thread.currentThread().interrupt(); System.out.println(Thread.interrupted()); //返回线程状态,并重置状态为false System.out.println(Thread.interrupted()); //再次调用返回false,因为interrupted()返回线程状态的同时,会重置线程的状态为false System.out.println("执行后"); 运行结果: 执行前 false true false 执行后 注意:线程的状态初始值为false, 调用start()方法启动线程前是false, 执行完后,如果是true会被重置为false 因此,此状态值是在线程执行过程中才有意义。 3.两个方法的区别: 1.isInterrupted()为非静态方法,interrupted()为静态方法。isInterrupted()查看的是调用此方法的线程的状态 interrupted()查看的是执行当前行代码的线程的状态 2.isInterrupted()不会重置状态为false,interrupted()调用完会重置状态为false 4.sleep()方法与线程停止 当线程停止状态为true时,调用sleep会抛异常 调用sleep()进行线程休眠,在休眠过程中,如果线程停止状态由false变为true时,也会抛异常 例子: Thread.sleep(1000); System.out.println("执行前,状态:" + Thread.currentThread().isInterrupted()); Thread.currentThread().interrupt(); System.out.println("执行后,状态:" + Thread.currentThread().isInterrupted()); Thread.sleep(1000); 运行结果: 执行前,状态:false 执行后,状态:true java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.huawei.controller.ThreadController.main(ThreadController.java:31) public class MyRunnable implements Runnable { private int count = 100; @Override public void run() { try { System.out.println("线程执行"); Thread.sleep(1000); //休眠 } catch (InterruptedException e) { e.printStackTrace(); } } } MyRunnable r = new MyRunnable(); Thread t1 = new Thread(r); t1.start(); t1.interrupt(); //线程休眠时,改变状态为true 运行结果: 线程执行 java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.huawei.thread.MyRunnable.run(MyRunnable.java:18) at java.lang.Thread.run(Thread.java:745) 5.让线程真正停止的方法,即不是改变停止状态,而是停止执行的方法:stop() //暴力终止线程执行,为已过时的方法 例子: public class MyRunnable implements Runnable { private int count = 100; @Override public void run() { try { for (int i = 0; i < 10; i++) { System.out.println("线程执行,循环次数:" + (i + 1)); Thread.sleep(1000); } } catch (InterruptedException e) { e.printStackTrace(); } } } MyRunnable r = new MyRunnable(); Thread t1 = new Thread(r); t1.start(); Thread.sleep(3000); t1.stop(); 运行结果: 线程执行,循环次数:1 线程执行,循环次数:2 线程执行,循环次数:3 //循环三次后,线程被终止,不再执行 //真正的停止 Process finished with exit code 0 调用slop()方法终止线程可能造成的问题: 1.可能使一些清理性的工作得不到完成 2.终止线程时会释放锁,这种释放是非正常释放,可能造成数据不一致问题。 6.不适用stop()完成线程终止: 采用停止状态进行控制,实现线程终止:如果停止状态为true,则抛出异常,或者使用return停止线程 例子: public class MyRunnable implements Runnable { private int count = 100; @Override public void run() { try { for (int i = 0; i < 10; i++) { System.out.println("线程执行,循环次数:" + (i + 1)); Thread.sleep(1000); if (Thread.interrupted()) { //检查状态 throw new InterruptedException(); //如果问停止状态,则抛异常终止代码运行 //return; //或者使用return终止,此时也会抛出InterruptedException异常 } } } catch (InterruptedException e) { System.out.println("线程终止,进行垃圾清理等工作。。。"); //线程执行停止后进行后续清理等工作 } } } MyRunnable r = new MyRunnable(); Thread t1 = new Thread(r); t1.start(); Thread.sleep(3000); t1.interrupt(); //调用interrupt方法改变停止状态而不是暴力终止
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构