多线程笔记:多线程基础 - 2
线程的暂停和恢复:即让线程暂时停止运行,并能恢复 suspend() 暂停线程。为已经过时方法 resume() 恢复暂停的线程。为已经过时的方法 例子 public class SuspendThread extends Thread{ private int i; public int getI() { return i; } public void setI(int i) { this.i = i; } @Override public void run() { super.run(); while (true) { i++; } } } SuspendThread thread = new SuspendThread(); thread.start(); Thread.sleep(1000); System.out.println(thread.getI()); Thread.sleep(1000); thread.suspend(); //线程暂停 System.out.println(thread.getI()); Thread.sleep(1000); System.out.println(thread.getI()); thread.resume(); //线程恢复 thread.sleep(1000); System.out.println(thread.getI()); 运行结果: 502839629 1079189339 1079189339 //线程暂停到恢复期间线程停止执行,i值不变 1721670999 这两个方法的缺点: 如果使用不当,极易造成公共的同步对象的独占,使得其他线程无法访问公共同步对象 如某个线程在同步的代码中暂停了,而没有恢复,则同步锁被永远占用。 这两个方法本身是不同步的,易造成数据不同步的情况 如: public class SuspendThread extends Thread{ private int i; private int j; public void setValue(int i, int j){ this.i = i; Thread.currentThread().suspend(); //线程启动后设置了i值后暂停,由于不同步,此时这个对象被其他线程访问则出现数据不一致问题 this.j = j; }; @Override public void run() { setValue(122, 333); } } SuspendThread thread = new SuspendThread(); thread.start(); Thread.sleep(100); System.out.println(thread.getI() + " " + thread.getJ()); //主线程获取到了子线程修改的成员变量 运行结果 : 122 0 yield()方法,为Thread的静态方法,作用是放弃当前cpu资源,将它让给其他任务去执行,当放弃的时间不确定。 可能刚放弃马上又获得cpu时间片 public class YieldThread extends Thread{ private int i; @Override public void run() { long begin = System.currentTimeMillis(); for (int k = 0; k < 50000000; k++) { i += k; } long end = System.currentTimeMillis(); System.out.println("不执行Thread.yield();时执行时间为:" + (end - begin) + "毫秒"); long begin2 = System.currentTimeMillis(); for (int k = 0; k < 50000000; k++) { Thread.yield(); //没次循环调用此方法 i += k; } long end2 = System.currentTimeMillis(); System.out.println("执行Thread.yield();时执行时间为:" + (end2 - begin2) + "毫秒"); } } YieldThread thread = new YieldThread(); thread.start(); 执行结果: 不执行Thread.yield();时执行时间为:16毫秒 执行Thread.yield();时执行时间为:24541毫秒 线程优先级: 在操作系统中,线程可以划分优先级,优先级较高的线程得到的cpu资源较多,cpu有限执行优先级较高的线程对象中的任务 1.设置线程优先级的方法: setPriority(); 2.优先级分为1-10 这10个等级,小于1或大于10将抛出 IllegalArgumentException异常 YieldThread thread1 = new YieldThread(); thread1.setName("优先级10的线程"); thread1.setPriority(10); thread1.start(); YieldThread thread2 = new YieldThread(); thread2.setName("优先级1的线程"); thread2.setPriority(1); thread2.start(); 运行结果: 优先级10的线程的线程执行时间为:171毫秒 //优先级高的执行快 //注意这里执行快不是因为这个线程先被main启动,与调用顺序无关 优先级1的线程的线程执行时间为:296毫秒 3.线程的优先级具有继承性:即A线程启动了B线程,则B线程的优先级和A相同 如: System.out.println("main线程优先级:" + Thread.currentThread().getPriority()); YieldThread thread = new YieldThread(); thread.start(); //主线程启动thread线程 System.out.println(thread.getName() + "线程优先级:" + thread.getPriority()); 运行结果: main线程优先级:5 Thread-0线程优先级:5 //继承了main线程的优先级 4.优先级具有随机性: 不能说优先级高就一定执行的更快,具有随机性,即大部分情况下优先级高的执行的快,是个概率问题 守护线程: java线程分为两种:用户线程和守护线程 守护线程是一种特殊的线程:又陪伴的含义,守护线程是为其他线程的运行提供便利服务的。 jvm示例中只要有非守护线程没有结束,守护线程就不会结束。只有当所有的非守护线程结束时,守护线程才会结束销毁 典型的守护线程:GC(垃圾回收器) 例子: public class DaemonThread extends Thread{ private int i; @Override public void run() { while (true) { try { System.out.println(i++); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { try { DaemonThread daemonThread = new DaemonThread(); daemonThread.setDaemon(true); //设置线程为守护线程 daemonThread.start(); Thread.sleep(5000); System.out.println("main主线程要结束了。守护线程将不再打印了,也会结束"); } catch (Exception e) { e.printStackTrace(); } } 运行结果: 0 1 2 3 4 main主线程要结束了。守护线程将不再打印了,也会结束 //主线程结束后,守护线程跟着结束
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具