线程是什么

进程是对CPU的抽象,而线程更细化了进程的运行流程

先看一下这个图

线程和进程的关系有

  1. 进程中就是线程在执行,所有(主)线程执行完了进程也就结束了
  2. 多个线程从1秒钟是同时运行完成,从1纳秒(或是更小的单位)看是排队执行
  3. 在不断运行的进程中(没有IO操作),使用多个线程并没有提高进程的执行效率,还有所降低

为什么需要多线程

我第一次使用线程是在学习BIO和多线程进行通信时
服务端每次接收到一个客户端的请求就创建一个线程(虽然可以使用tomcat和Netty大大优化了BIO,但它们也使用了多线程)

就这个用法而言,难道不能用多进程代替多线程进行通信吗(不知道提出这个问题是不是太笨了)

我的理解是:

  1. 多个客户端和服务端通信时,服务端有很多资源是多个客户端共用的
  2. 如果使用多进程,也就是运行很多个服务端,相同服务端就得存放相同的资源在电脑内存中,太浪费空间了(如果是为了防止故障存在多台机器肯定就不浪费)
  3. 所以创建了线程这个概念去共用进程的资源

线程需要什么

  业务场景还是在通信中

  • 服务端线程需要在客户端发消息过来时及时响应,至于怎么响应肯定就写在自己的代码逻辑里

    • 所以线程需要一段可以执行的代码块
  • A发消息,就得切换到与A通信的线程,B发消息,就得切换到与B通信的线程,线程就得不停的切换
    • 所以CPU得知道哪个线程和A通信等,就得给线程个ID好辨认

总之线程还需要各种各样我没学过的东西。

下面根据自己的理解,实现一个简单的用户线程

用户线程:如果里面有一个线程执行不下去了(等待输入、运行报错、死循环),操作系统并不认识用户线程,只认识用户进程,会让整个用户进程执行不下去

实现一个简单的用户线程

线程的数据结构

MyThread.java

 1 import java.lang.reflect.Constructor;
2 import java.lang.reflect.InvocationTargetException;
3 import java.lang.reflect.Method;
4
5 public class MyThread<T> {
6
7 private int Id;//区分各个线程的标识符
8 private int runTime;//线程当前可以运行的时间片
9 private int totalTime; //线程总共需要运行的时间
10 private int priority;//线程的优先级
11 //交给线程执行的代码块,用一个对象参数替代
12 public T data;
13
14 public MyThread() {
15 }
16
17 public MyThread(int id, int totalTime,int priority, T data) {
18
19 this.Id = id;
20 // this.runTime = runTime;
21 this.totalTime = totalTime;
22 this.runTime = totalTime/2;//固定线程每次运行时间片是总时间的二分之一,方便测试
23 this.priority = priority;
24 this.data = data;
25 }
26
27 public void run(){
28
29 try {
30
31 System.out.println("线程id:"+Id);
32 System.out.println("剩余时间片:" + runTime);
33 System.out.println("线程优先级:"+priority);
34
35 //使用java的反射机制,执行代码块的内容
36 Class<?> clazz = data.getClass();
37 Constructor constructor = clazz.getDeclaredConstructor();
38 Object object = constructor.newInstance();
39
40 Method method = clazz.getMethod("hello");
41 method.invoke(object);
42
43 //每执行一次,线程总时间减少
44 //运行的时间片不变
45 totalTime-=runTime;
46 // 判断线程运行总时间是否快要结束了
47 runTime = Math.min(totalTime,runTime);
48
49 } catch (NoSuchMethodException e) {
50 e.printStackTrace();
51 } catch (InvocationTargetException e) {
52 e.printStackTrace();
53 } catch (InstantiationException e) {
54 e.printStackTrace();
55 } catch (IllegalAccessException e) {
56 e.printStackTrace();
57 }
58
59 }
60
61 public int getPriority() {
62 return priority;
63 }
64
65 public int getRunTime() {
66 return runTime;
67 }
68
69 public int getTotalTime() {
70 return totalTime;
71 }
72 }

写一个类代替代码块供线程执行

 1 public class MyMethod {
2
3 public MyMethod() {
4
5 }
6
7 public void hello(){
8 System.out.println("hello");
9 }
10
11 }

测试线程的执行

 1 import java.util.Comparator;
2 import java.util.PriorityQueue;
3 public class Test {
4
5 public static void main(String[] args) {
6
7 //由优先队列进行线程的调度,即优先级高的线程先执行,优先级相同采用先入先出算法
8 PriorityQueue<MyThread> priorityQueue = new PriorityQueue<>(new Comparator<MyThread>() {
9 @Override
10 public int compare(MyThread o1, MyThread o2) {
11 return o2.getPriority() - o1.getPriority();
12 }
13 });
14
15 MyMethod method = new MyMethod();
16 //创建三个线程
17 MyThread<MyMethod> myThread = new MyThread<>(1,3,5,method);
18 MyThread<MyMethod> myThread1 = new MyThread<>(2,3,5,method);
19 MyThread<MyMethod> myThread2 = new MyThread<>(3,2,10,method);
20 //线程进入队列
21 priorityQueue.offer(myThread);
22 priorityQueue.offer(myThread1);
23 priorityQueue.offer(myThread2);
24
25 //在循环中不断的执行线程
26
27 while (!priorityQueue.isEmpty()){
28
29 MyThread<MyMethod> myThreadRun = priorityQueue.poll();
30
31 myThreadRun.run();
32
33 //线程总时间不为0,进入队列等待下次执行
34 if (myThreadRun.getTotalTime() != 0){
35 priorityQueue.offer(myThreadRun);
36 }
37 }
38
39 System.out.println("线程都执行完了,进程也就结束了");
40 }
41 }

执行结果

总结

  1. 这个用户线程的例子实现的不好
  2. 例子中总共有四个线程,主线程担任了一个调度线程的职责
  3. 在操作系统中,线程的执行
    • 操作系统会不断主动去询问线程的时间片结束没,一旦结束就将线程换下
  4. 多线程排队执行出现竞争
    • 一个线程执行一个打印命令,对应了CPU中的多条指令
    • 如果指令没执行完,切换到了其他线程,再换回来执行指令,就会出现一种竞争的情况

Java:学习什么是多线程的更多相关文章

  1. Java学习手记2——多线程

    一.线程的概念 CPU执行程序,就好比一个人在干事情一样,同一个时间你只能做一件事情,但是这样的效率实在是太低了,在你用电脑的时候,听歌就不能浏览网页,看电影就不能下载视频,你想想是不是很蛋疼. 所以 ...

  2. 【原】Java学习笔记032 - 多线程

    package cn.temptation; public class Sample01 { public static void main(String[] args) { /* * [进程]:正在 ...

  3. Java学习笔记之——多线程

    多线程编程 程序: 进程:一个程序运行就会产生一个进程 线程:进程的执行流程,一个进程至少有一个线程,称为主线程 如:QQ聊着天,同时在听音乐 一个进程可以有多个线程,多个线程共享同一个进程的资源 线 ...

  4. java学习之路--多线程实现的方法

    1 继承Thread类 继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Th ...

  5. Java学习笔记:多线程(一)

    Java中线程的五种状态: 新建状态(New) 就绪状态(Runnable) 运行状态(Running) 阻塞状态(Blocked) 凋亡状态(Dead) 其中阻塞状态(Blocked)又分为三种: ...

  6. Java学习之并发多线程理解

    1.线程简介: 世间万物会同时完成很多工作,如人体同时进行呼吸.血液循环.思考问题等活动,用户既可以使用计算机听歌也可以使用它打印文件,而这些活动完全可以同时进行,这种思想在Java中称为并发,而将并 ...

  7. java学习笔记(5)多线程

    一.简介(过段时间再写,多线程难度有点大) --------------------------------------- 1.进程:运行时的概念,运行的应用程序 2.线程:应用程序内部并发执行的代码 ...

  8. Java 学习笔记(11)——多线程

    Java内部提供了针对多线程的支持,线程是CPU执行的最小单位,在多核CPU中使用多线程,能够做到多个任务并行执行,提高效率. 使用多线程的方法 创建Thread类的子类,并重写run方法,在需要启动 ...

  9. Java学习笔记:多线程(二)

    与线程生命周期相关的方法: sleep 调用sleep方法会进入计时等待状态,等待时间到了,进入就绪状态. yield 调用yield方法会让别的线程执行,但是不确保真正让出.较少使用,官方注释都说 ...

  10. JAVA学习之路(多线程)---模拟售票(细解)

    首先看题目描述: 假设有火车票100张,创建4个线程模拟4个售票点,每100ms售出一张,打印出售票过程,格式如下: 窗口3:卖出第100张票 窗口4:卖出第99张票 ............ ... ...

随机推荐

  1. 利用漏洞破解win7密码

    一.利用5次shift漏洞破解win7密码 1.在未登录系统时,连续按5次shift键,弹出程序:C:\Windows\system32\sethc.exe 2.部分win7及win10可通过系统修复 ...

  2. 为了让她学画画——熬夜用canvas实现了一个画板

    前言 大家好,我是Fly, canvas真是个强大的东西,每天沉迷这个无法自拔, 可以做游戏,可以对图片处理,后面会给大家分享一篇,canvas实现两张图片找不同的功能, 听着是不是挺有意思的, 有点 ...

  3. Markdown 样式美化大全

    Markdown 样式大全 目录 Markdown 样式大全 1. 键盘 2. 路径 3. 彩色字体背景 4. 折叠 5. 锚点链接 原生锚点1 原生锚点2 Hello Hello 6. 待办列表 7 ...

  4. python3中文件/IO编程

    python3的文件操作可谓是我见过所有语言中最舒服的,那我们来一起看一下py3中的文件操作. 1:文件的打开方式有以下几种: 注:以上图表参考菜鸟教程 2:定位读写文件  f = open(&quo ...

  5. 开源低代码平台开发实践二:从 0 构建一个基于 ER 图的低代码后端

    前后端分离了! 第一次知道这个事情的时候,内心是困惑的. 前端都出去搞 SPA,SEO 们同意吗? 后来,SSR 来了. 他说:"SEO 们同意了!" 任何人的反对,都没用了,时代 ...

  6. (python函数04)zip(*sorted(zip()))

    zip(*sorted(zip())) 用这个玩意儿可以以对两个迭代对象进行排序. 示例代码01  cnts = [2, 4, 3, 6, 5] boundingBoxes = [(730, 20, ...

  7. SAS 按自定义顺序对观测进行排序

    本文链接:https://www.cnblogs.com/snoopy1866/p/15091967.html 实际项目中会经常遇到按指定顺序输出Listing的情况,例如:输出所有受试者的分组情况列 ...

  8. solr(CVE-2020-13957)文件上传

    影响版本 Apache Solr 6.6.0 - 6.6.5 Apache Solr 7.0.0 - 7.7.3 Apache Solr 8.0.0 - 8.6.2 环境搭建 下载环境 http:// ...

  9. ES11中的bigint

    上一周小编因为自己的事情,没有持续更新,还望大家谅解,趁着今天醒得早,小编继续和大家学(si)习(ke)es11中的新语法.在js中,对整数类型的数据,存在着最大极限,这个极限就是 const max ...

  10. vue 子目录配置,负载均衡 nginx

    1. 我使用的是,腾讯云做负载均衡. 负载均衡配置: https://www.xxxx.com/vue   域名指向的服务器地址:10.10.10.10:80/vue 2. nginx 配置: ser ...