线程是什么

进程是对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. FreeRTOS-00-基础知识+任务创建删除

    1 说明 本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正. 1.1 简介 FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式.合作式和时间片 ...

  2. [网络流24题]最长k可重区间集[题解]

    最长 \(k\) 可重区间集 题目大意 给定实心直线 \(L\) 上 \(n\) 个开区间组成的集合 \(I\) ,和一个正整数 \(k\) ,试设计一个算法,从开区间集合 \(I\) 中选取开区间集 ...

  3. C语言的编译与链接

    C语言源文件要经过编译.链接才能生成可执行程序:编译(Compile)会将源文件(.c文件)转换为目标文件.对于 VC/VS,目标文件后缀为.obj:对于GCC,目标文件后缀为.o.编译是针对单个源文 ...

  4. 家庭账本开发day11

    编写登录界面和个人信息查看界面 $.ajax({                    url: "UserServlet?method=login",//url          ...

  5. 【LeetCode】137. 只出现一次的数字 II(剑指offer 56-II)

    137. 只出现一次的数字 II(剑指offer 56-II) 知识点:哈希表:位运算 题目描述 给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 .请你找出并返回 ...

  6. 超详细!Vuex手把手教程

    目录 1,前言 2,Vuex 是什么 3,5大属性说明 4,state 4.1 直接访问 4.1 使用mapState映射 5,getters 5.1 先在vuex中定义getters 5.2 直接获 ...

  7. java反序列化提取payload之xray 高级版的shiro回显poc的提取过程

    本文中xray高级版shiro payload来源于雷石安全实验室公众号发布的shiroExploit.jar 感谢雷石安全实验室,雷石安全实验室牛逼 本文主要描述如何从shiro的payload中提 ...

  8. 【LeetCode】404. 左叶子之和

    404. 左叶子之和 知识点:二叉树 题目描述 计算给定二叉树的所有左叶子之和.. 示例 3 / \ 9 20 / \ 15 7 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24 解 ...

  9. CF1032G Chattering

    CF1032G Chattering 题意 思路 对于每一个位置,它转移的范围是确定的. 对于一段可以走到的区间,我们可以求出区间中所有点再能走到区间范围. 于是这个就可以倍增进行转移. 如何快速求出 ...

  10. 7.29考试总结(NOIP模拟27)[牛半仙的妹子图·Tree·序列]

    前言 从思路上来讲是比较成功的,从分数上就比较令人失望了. 考场上是想到了前两个题的正解思路,其实最后一个题是半个原题,只可惜是我看不懂题... 这波呀,这波又是 语文素养限制OI水平.. 改题的时候 ...