微信网站模板源码下载在网上做贸易哪个网站好
web/
2025/9/26 21:53:50/
文章来源:
微信网站模板源码下载,在网上做贸易哪个网站好,求人做网站,有哪些做特卖的网站线程的概念
前言#xff1a; 一个程序运行起来#xff0c;就会对应一个进程#xff0c;例如#xff0c;启动一个 Java 程序#xff0c;就会创建一个 Java 进程。进程也被称为系统分配资源的基本单位。
一个进程可以包含一个线程#xff0c;也可以包含多个线程#xff…线程的概念
前言 一个程序运行起来就会对应一个进程例如启动一个 Java 程序就会创建一个 Java 进程。进程也被称为系统分配资源的基本单位。
一个进程可以包含一个线程也可以包含多个线程不能包含0个线程线程是系统调度执行的基本单位也被称为轻量级(Lignt Weight Process) 创建线程
关于线程的创建各位亲们请详见博主的另一篇博客《Java 中创建线程(Thread)的五种方法》 使用多线程的原因
主要原因
单核CPU的发展遇到了瓶颈要想提高算力就需要多核CPU而并发编程能更充分利用多核CPU资源将计算逻辑分配到多个处理器核心上显著减少程序的运行时间并且随着更多处理器核心的加入而变得更加高效有些任务场景需要等待IO为了让等待IO的时间能够去做一些其他的工作也需要用到并发编程。 理解 就比如一些复杂的业务逻辑当你在京东App上购物时你购买一个东西时就涉及到了一笔订单的创建插入订单数据生成订单快照发送邮件通知卖家和记录货品销售数量等。作为用户的你从确认订购开始就要等待上述的操作全部完成才能看到订购成功的结果。 解决 使用多线程技术将比如生成订单快照发送邮件等数据一致性不强的操作派发给其它的线程就可以显著缩短响应时间从而提示用户购物体验
次要原因 虽然多进程也能实现并发编程但是线程比进程更轻量同一个进程的线程之间共享了资源 ( 内存文件描述符表等) 体现如下 1.创建线程比创建进程更快 2.销毁线程比销毁进程更快 3.调度线程比调度进程更快
进程的状态
Java 线程的状态
状态名称说明NEWThread 对象有了但还没调用 start()系统内部的线程还未创建RUNNABLE就绪状态指的是这个线程“随叫随到”以下 2 种情况1. 这个线程正在 CPU 执行2. 这个线程虽然没在 CPU 执行但是随时可以调度到 CPU 上执行TERMINATED线程已经终止了内核中的线程已经销毁了但是 Thread 对象还在WAITING阻塞死等进入的阻塞TIMED_WAITING阻塞在进行带有超时时间的等待BLOCKED阻塞进行锁竞争的时候产生的阻塞
注只要线程出现WAITINGTIMED_WAITING BLOCKED 中的任意一个状态都是阻塞只是产生这几个状态的原因不一样 作图理解 启动线程
线程对象在初始化完成之后调用 start() 方法就可以启动。 线程 start() 方法的含义是当前线程同步告知 Java 虚拟机只要线程规划器空闲应立即启动调用 start() 方法的线程。 调用 start 方法才真的在操作系统的底层创建出一个线程 中断/终止线程
中断可以理解为线程的一个标识位属性它表示一个运行中的线程是否被其他线程进行了中断操作。
终止线程在Java中 都只是提醒,建议真正要不要终止还得线程本体来进行决定的!! t 线程正在执行其他线程只能提醒一下t是不是要终止了t 收到这样的提醒之后也还是得自己决定的。终止就好比其他线程对该线程打了一个招呼
停止线程的常见方式有以下2种
通过共享的标记来进行沟通调用 interrupt() 方法来通知
示例1: 使用自定义的变量来作为标志位 核心思路让需要终止的线程的入口方法尽快执行结束(跳出循环,还是尽快return都可以) 代码示例
package Thread;/*** Created with IntelliJ IDEA.* Description:* User: fly(逐梦者)* Date: 2024-03-29* Time: 10:44*/
public class Demo10 {private static boolean isRunning true;public static void main(String[] args) {Thread t new Thread(()- {while (isRunning){System.out.println(hello thread);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println(t 线程已经结束了);});t.start();try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}// 3s 之后主线程修改 isRunning 的值从而通知 t 结束System.out.println(控制 t 线程结束);isRunning false;}
}这里的isRunning不能设置为局部变量只能设置为静态成员变量
原因 涉及到变量捕获作为lambda或者匿名内部类都能捕获到外面一层作用域中的变量名就可以使用的。 但是变量捕获有一个前置条件就是要求变量得是final(常量)或者“事实 finalisRunning变量涉及到修改操作变量捕获失败javac 无法编译通过编译器会给你爆红提示报错 设置为静态成员变量就不是变量捕获了而是内部类访问外部类的成员此时 lambda 本质上就是一个匿名内部类实现了函数式接口
上述代码的缺点 有些情况下main 线程是无法及时把 t 线程终止掉
代码运行结果 示例2: 使用 Thread.interrupted() 代替自定 义标志位 刚才是定义了一个boolean变量实际上Thread 里面内置了一个使用内置的标志位功能要更强大 代码示例
package Thread;/*** Created with IntelliJ IDEA.* Description:* User: fly(逐梦者)* Date: 2024-03-29* Time: 11:19*/
public class Demo11 {public static void main(String[] args) {Thread t new Thread(() - {while (!Thread.currentThread().isInterrupted()) {System.out.println(hello thread);try {Thread.sleep(1000);} catch (InterruptedException e) {
// throw new RuntimeException(e);e.printStackTrace();}}});t.start();try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}t.interrupt();}
} Thread.currentThread() 是个static方法这个方法能够获取到当前线程可以能够获取到 t 这个引用 isInterrupted() 线程内置的标志位boolean 类型变量true 表示线程要终止了false表示线程要继续执行 t.interrupt() 这个方法相当于示例1的设置 boolean 值为 true并且除了能设置boolean值还可以唤醒 sleep等阻塞的方法。即使正在sleep(10s)刚休眠1s按照示例1/第一种写法必须再等待9s才能让线程结束(sleep结束了,才能继续进行循环判定); 示例2/第二种写法则立即就会让 sleep抛出一个InterruptedException异常不会再等待立即就唤醒了 当使用 Interrupt 方法之后此时要不要结束都是t线程自己决定的!!!
代码运行结果 现象 sleep 在抛出异常后没有立即终止而是继续循环打印。 原因 出现这个现象,还是 sleep在搞鬼 如果代码没有sleep确实是直接修改了标志位就完了 如果有 sleep,并且是触发 Interrupt 的时候线程正在 sleepsleep 被唤醒的同时就会清除刚才的标志位(又改回false ) 之所以要改回来就是把控制权转交给作为程序员的我们.
如果想立即结束直接在 catch 语句中加个break, 即可。至于稍后结束还是不想结束稍微修改下代码就行了 相关代码 Thread t new Thread(() - {while (!Thread.currentThread().isInterrupted()) {System.out.println(hello thread);try {Thread.sleep(1000);} catch (InterruptedException e) {
// throw new RuntimeException(e);
// e.printStackTrace();break;}}});t.start();运行结果
线程等待
存在问题的代码
public static void main(String[] args) {Thread t new Thread(()-{System.out.println(hello thread);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}});t.start();for (int i 0; i 3; i) {System.out.println(hello main);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println(main end);
}运行结果 分析原因
根本原因 多个线程在系统中的调度顺序是无序的(抢占式执行)作为程序猿的我们期望程序的结果是稳定的不应该是随机的 希望在随机的体系上加入一些控制让结果变的不那么随机
问题 多个线程什么时候被调度执行不确定 多个线程谁先执行结束不确定
解决 通过线程等待(join)来确定线程结束的先后顺序
join 相关函数
函数返回值方法及其作用个人理解voidjoin()Waits for this thread to die.这个join无参数版本 (很少使用)死等不见不散只要 t 不结束join 就会一直等待下去voidjoin(long millis)Waits at most millis milliseconds for this thread to die.常用等待 N 毫秒 比如写了等待10ms如果10ms之内, t 线程结束了直接返回如果10ms 到了t 还没结束不等了代码继续往下执行了voidjoin(long millis, int nanos)Waits at most millis milliseconds plus nanos nanoseconds for this thread to die.等待 N 毫秒 又 M 纳秒 (几乎不用)
具体实现 由于上述代码中 main 和 t 线程之间的结束顺序是不确定的如果希望让代码里面的t能够先结束, main后结束,就可以在main 中使用线程等待(join)
代码如下
package Thread;/*** Created with IntelliJ IDEA.* Description:* User: fly(逐梦者)* Date: 2024-03-30* Time: 2:06*/
public class Demo12 {public static void main(String[] args) throws InterruptedException {Thread t new Thread(() - {for (int i 0; i 3; i) {System.out.println(hello thread);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t.start();for (int i 0; i 3; i) {System.out.println(hello main);try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}t.join();System.out.println(main end);}
}运行结果 main 中调用上述 join 方法有以下两种可能: 1.如果t线程此时已经结束了此时join 就会立即返回 没涉及到任何阻塞操作直接往下执行了 2.如果t线程此时还没结束此时 join 就会 阻塞 等待一直等待到t线程结束之后, join才能解除阻塞,继续执行 这就确保了 main 线程—定是后结束 阻塞 该线程暂时不参与cpu调度执行解除阻塞继续执行线程重新参与到cpu调度了
注意可怜的main线程 - main 一般情况都不会被其它线程 join即是不会被等待的 ~~ 批准main 你什么时候才能摆脱舔狗的身份啊
线程安全
批注(#^.^#) 浅谈一下接下来的博客会详细的讲讲多线程带来的线程安全
线程安全问题的原因: 1.抢占式执行随机调度 2.多个线程同时修改同一个变量 3.修改操作不是原子的 4.内存可见性 5.指令重排序
解决线程安全问题: 加锁(synchronized)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/82406.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!