建设局的证件在哪个网站查,wordpress登录无效用户名,建设手机网站包括哪些费用,网站入侵怎么做文章目录一、认识线程1. 线程的概念2. 出现多线程的原因3. 进程与线程4. 对多线程的详细解释二、初次实现多线程代码1. 初步了解2. 使用 Java 中的工具查看当前的所有线程3. Java 中创建线程的多种方式一、认识线程
1. 线程的概念
所谓线程#xff0c;就是指在一个 ‘执行流…
文章目录一、认识线程1. 线程的概念2. 出现多线程的原因3. 进程与线程4. 对多线程的详细解释二、初次实现多线程代码1. 初步了解2. 使用 Java 中的工具查看当前的所有线程3. Java 中创建线程的多种方式一、认识线程
1. 线程的概念
所谓线程就是指在一个 ‘执行流’ 中多个线程之间都可以按照自己的顺序执行代码多个线程之间可以 ‘同时’ 执行多个代码。
2. 出现多线程的原因
首先并发编程成为了刚需。
随着科技的发展目前 CPU 的核心已近难以在进行缩小想要得到更高的算力 “多核” CPU 成为了一种可行的解决方案因此并发编程来利用 CPU 资源的操作应运而生。有些任务操作中需要等待 “IO”为了让等待的时间不被浪费此时多线程的优势就体现了出来。
其次虽然 多进程 也可以实现 并发编程但是线程 比 进程 更加轻量
注 所谓轻量就是在解决并发编程的前提下让创建销毁调度的速度更快一些。
线程为啥更轻就是将 申请资源释放资源 的操作省去了 下面我给大家简单举一个生活中的例子来解释一下。
我们先设想一个物流的中转站如图 这里就类似于一个进程在执行相关操作。
此时因为某些原因运输到我们中转站管辖范围的货物突然增多为了更好的对快递进行配送我们就必须要扩建。
无需多虑这里会有两种操作可供我们选择。
操作一重新在城市中找一块地方建立一个新仓库用来缓解物流压力。 如图就是将原来的模式完全复制一份。相当于 多进程 方案
操作二将原来的厂房进行整理在其中新建一个仓库即可。 这里不难发现第二种方案显然比第一种方案成本要小很多场地和快递分配体系都是可以套用之前的。
这就是 多线程 版本的方案此时只要在第一次申请资源时合理申请之后增加的操作只需要复用第一次的申请的资源即可不需要在进行资源的申请等操作…
3. 进程与线程
线程和进程的关系进程 包含 线程。 一个进程中至少包含一个线程一个进程可以包含多个线程。
进程和线程的关系图表如下所示 我们可以清晰地观察到同一个进程中的多线程共用着同一份资源主要指内存文字描述符表
注
进程是系统 资源分配 的最小单位线程是系统 调度 的最小单位。一个 线程 是通过一个 PCB 来描述即PCB中的状态上下文优先级记账信息等每一个 线程 都是独立拥有的。在 同一个进程 的 多个线程 中 PCB 之间他们的 pid 是相同的即内存指针和文件描述符表是相同的。
4. 对多线程的详细解释
对于多线程的解释在这里我们依然可以用一个比较有趣的例子来解释。
首先我们可以设想一个华强劈瓜的情景。 现在我们知道要想让华强更好的更快的进行劈瓜就需要让华强分身到一个房间中一块劈即多线程。
此时我们让华强老铁造出更多分身出现在房间中呢么劈瓜效率就一定会很快吗 如图 其实不难发现华强老铁的增多并不能无限的加快劈瓜的速度。 桌子周围的空间是有限的 即CPU 上的核心数量是有限的。 华强老铁太多最终会出现相互推嚷的情况让正在用力劈瓜的华强劈歪来。也就是说线程数量太多核心数量有限使得大量的时间花费在了线程调度上了
在多线程的条件下如果某两个华强老铁一眼看上了同一个瓜争抢着去劈此时就可能会打架。 这种情况在 多进程 中就不会出现因为多进程是将瓜分配到单独的房间由一个华强老铁来劈的。 因此这里就引出了一个线程安全问题。
多线程下还会有一个问题 两个华强同时看上一个瓜1号华强率先下手劈了瓜2号华强很生气直接就把瓜摊子掀了大家都劈不了了。也就是说如果一个线程出现了问题如果没有处理好呢么就有可能导致整个进程崩溃其他线程也就被迫停止了
二、初次实现多线程代码
1. 初步了解
首先我们要知道在 Java 中要实现多线程的一个关键的类 Thread 类。 这里我先展示一段代码之后再进行详细的解释。
class MyThread extends Thread{//重写线程类中的 run 方法public void run(){while(true){System.out.println(hello thread);//为了让执行变慢加一个 sleeptry {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}public class ThreadDemo {public static void main(String[] args) {Thread t new MyThread();//一个线程的创建t.start();//main 方法中主线程的代码实现while(true){System.out.println(hello main);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}此处的 start 就只是创建了一个新的线程注意start 没有调用 run 方法。
这里创建新线程就是调用操作系统的 API 通过操作系统内核创建出此线程的 PCB并且将要执行的指令传递给这个 PCB当 PCB 被调度到 CPU 上时就会执行到其中的 run 方法中。 简单来讲就是 main 方法中的 start 创建新线程新线程内调用 run 方法。
start 和 run 方法之间的区别 start是真正的从系统资源里创建的独立的执行流。 run 方法只是描述了线程中需要干的工作。在main 方法中调用 run 此时没有创建任何线程只有 main 线程在进行工作
代码执行结果 注这里只是部分结果截取。
在上述的结果中我们不难看出两个线程之间执行的先后顺序似乎并不固定这里就需要提到操作系统调用线程时的方式——抢占式调用。
因此哪个进程线上那个进程后上完全是取决于操作系统调度器的具体实现策略。
2. 使用 Java 中的工具查看当前的所有线程
1在安装 jdk 的 bin 目录下找到上图中的 jconsole 程序。
如图所示 2运行多个线程的代码的同时打开程序。 3选择自己的线程后连接之后点击线程左下角就会出现如下图的情况。 3. Java 中创建线程的多种方式
继承 Tread 重写 run 方法。
class MyThread extends Thread{//重写线程类中的 run 方法public void run(){while(true){System.out.println(hello thread);//为了让执行变慢加一个 sleep}}
}public class ThreadDemo1 {public static void main(String[] args) {Thread t new MyThread();//start 表明创建一个线程新线程t.start();while(true){System.out.println(hello main);}}
}实现 Runnable 接口
// Runnable 作用是描述一个“要执行的任务”run方法就是任务执行的细节
class MyRunnable implements Runnable{Overridepublic void run() {System.out.println(hello thread);}
}public class ThreadDemo2 {public static void main(String[] args) {//这只是描述了个任务Runnable runnable new MyRunnable();//把任务交给线程执行Thread t new Thread(runnable);t.start();}
}使用 匿名内部类 来继承 Thread 方法。
//使用匿名内部类来实现线程的创建
public class ThreadDemo3 {public static void main(String[] args) {//这里创建了 Thread 的子类但是子类没有名称//但是创建了子类的实例让 t 指向了该实例并重写了其中的 run 方法。Thread t new Thread(){public void run(){System.out.println(hello);}};t.start();}
}使用 匿名内部类 实现 Runnable
这里的匿名内部类不需要再进行解释
public class ThreadDemo4 {public static void main(String[] args) {//这里与第二种方法极为相似是直接将 runnable 实例化后传递给匿名内部类Thread t new Thread(new Runnable(){Overridepublic void run() {System.out.println(hello);}});t.start();}
}使用 Lambad 表达式
// lambda 表达式
public class ThreadDemo5 {public static void main(String[] args) {Thread t new Thread(() - {System.out.println(hello);});t.start();}
}到此, 文章结束, 如有不足, 欢迎提出. 如有错误, 欢迎指正!