多线程到底重不重要?

我们先说一下为什么要讲多线程和高并发?

原因是,你想拿到一个更高的薪水,在面试的时候呈现出了两个方向的现象:

第一个是上天

  • 项目经验
  • 高并发 缓存 大流量 大数据量的架构设计

第二个是入地

  • 各种基础算法,各种基础的数据结构
  • JVM OS 线程 IO等内容

多线程和高并发,就是入地里面的内容。

基本概念

我们先从线程的基本概念开始,给大家复习一下,不知道有多少同学是基础不太好,说什么是线程都不知道的,如果这样的话,花时间去补初级内容的课。

什么是叫一个进程? 什么叫一个线程?

Program app ->QQ.exe

**进程:**做一个简单的解释,你的硬盘上有一个简单的程序,这个程序叫QQ.exe,这是一个程序,这个程序是一个静态的概念,它被扔在硬盘上也没人理他,但是当你双击它,弹出一个界面输入账号密码登录进去了,OK,这个时候叫做一个进程。进程相对于程序来说它是一个动态的概念

**线程:**作为一个进程里面最小的执行单元它就叫一个线程,用简单的话讲一个程序里不同的执行路径就叫做一个线程

示例:什么叫做线程

package com.mashibing.juc.c_000;
import java.util.concurrent.TimeUnit;
public class T01_WhatIsThread {	private static class T1	extends Thread {@Override														public void run() {for(int i=0; i<10; i++) {try {TimeUnit.MICROSECONDS.sleep(1);} catch (InterruptedException e) { e.printStackTrace();}System.out.println("T1");}}}public static void main(String[] args) {//new T1().run();new T1().start();for(int i=0; i<10; i++) {try {TimeUnit.MICROSECONDS.sleep(1);} catch (InterruptedException e) { e.printStackTrace();}System.out.println("main");}}
}

观察上面程序的数据结果,你会看到字符串“T1”和“Main”的交替输出,这就是程序中有两条不同的执行路径在交叉执行,这就是直观概念上的线程,概念性的东西,理解就好,没有必要咬文嚼字的去背文字的定义。

创建线程的几种方式

package com.mashibing.juc.c_000;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;public class T02_HowToCreateThread {static class MyThread extends Thread {@Overridepublic void run() {System.out.println("Hello MyThread!");}
}static class MyRun implements Runnable {@Overridepublic void run() {System.out.println("Hello MyRun!");}
}static class MyCall implements Callable<String> {@Overridepublic String call() {System.out.println("Hello MyCall"); return "success";}
}//启动线程的5种方式public static void main(String[] args) {new MyThread().start();new Thread(new MyRun()).start(); new Thread(()->{System.out.println("Hello Lambda!");}).start();Thread t = new Thread(new FutureTask<String>(new MyCall()));t.start();ExecutorService service = Executors.newCachedThreadPool(); service.execute(()->{System.out.println("Hello ThreadPool");});service.shutdown();
}}

分享一道面试题

请你告诉我启动线程的三种方式 ?

你说第一个:new Thread().start(); 第二个: new Thread(Runnable).start() 这没问题 ;那第三个呢,要回答线程池也是用的这两种之一,他这么问有些吹毛求疵的意思,你就可以说通过线程池也可以启动一个新的线程 3:Executors.newCachedThreadPool()或者FutureTask + Callable

我们来认识几个线程的方法

package com.mashibing.juc.c_000; 
public class T03_Sleep_Yield_Join { public static void main(String[] args) { //testSleep(); //testYield(); testJoin();} /*Sleep,**意思就是睡眠,当前线程暂停一段时间让给别的线程去运行。**Sleep**是怎么复活的?由你的睡眠时间而定,等睡眠到规定的时间自动复活***/ static void testSleep() { new Thread(()->{ for(int i=0; i<100; i++) { System.out.println("A" + i); try { Thread.sleep(500);//TimeUnit.Milliseconds.sleep(500)} catch (InterruptedException e) { e.printStackTrace();}}}).start();}/*Yield,就是当前线程正在执行的时候停止下来进入等待队列,回到等待队列里在系统的调度算法里头呢还是依然有可能把你刚回去的这个线程拿回来继续执行,当然,更大的可能性是把原来等待的那些拿出一个来执行,所以yield的意思是我让出一下CPU,后面你们能不能抢到那我不管*/static void testYield() {new Thread(()->{for(int i=0; i<100; i++) {System.out.println("A" + i);if(i%10 == 0) Thread.yield();}}).start();new Thread(()->{for(int i=0; i<100; i++) {System.out.println("------------B" + i);if(i%10 == 0) Thread.yield();}}).start();
}/*join, 意思就是在自己当前线程加入你调用Join的线程(),本线程等待。等调用的线程运行完了,自己再去执行。t1和t2两个线程,在t1的某个点上调用了t2.join,它会跑到t2去运行,t1等待t2运行完毕继续t1运行(自己join自己没有意义) */static void testJoin() {Thread t1 = new Thread(()->{for(int i=0; i<100; i++) {System.out.println("A" + i);try {Thread.sleep(500);//TimeUnit.Milliseconds.sleep(500)} catch (InterruptedException e) {e.printStackTrace();}}});Thread t2 = new Thread(()->{try {t1.join();} catch (InterruptedException e) { e.printStackTrace();}for(int i=0; i<100; i++) {System.out.println("A" + i);try {Thread.sleep(500);//TimeUnit.Milliseconds.sleep(500)} catch (InterruptedException e) { e.printStackTrace();}}});t1.start();t2.start();}
}

线程状态

常见的线程状态有六种:

当我们new一个线程时,还没有调用start()该线程处于新建状态

线程对象调用 start()方法时候,他会被线程调度器来执行,也就是交给操作系统来执行了,那么操作系统来执行的时候,这整个的状态叫Runnable,Runnable内部有两个状态**(1)Ready就绪状态/(2)Running运行状态**。就绪状态是说扔到CPU的等待队列里面去排队等待CPU运行,等真正扔到CPU上去运行的时候才叫Running运行状态。(调用yiled时候会从Running状态跑到Ready状态去,线程配调度器选中执行的时候又从Ready状态跑到Running状态去)

如果你线程顺利的执行完了就会进去**(3)Teminated****结束状态**,(需要注意Teminated完了之后还可不可以回到new状态再调用start?这是不行的,完了这就是结束了)

在Runnable这个状态里头还有其他一些状态的变迁**(4)TimedWaiting等待、(5)Waiting等待、(6)Blocked阻塞**,在同步代码块的情况就下没得到锁就会阻塞状态,获得锁的时候是就绪状态运行。在运行的时候如果调用了o.wait()、t.join()、LockSupport.park()进入Waiting状态,调用o.notify()、o.notifiAll()、LockSupport.unpark()就又回到Running状态。TimedWaiting按照时间等待,等时间结束自己就回去了,Thread.sleep(time)、o.wait(time)、t.jion(time)、LockSupport.parkNanos()、LockSupport.parkUntil()这些都是关于时间等待的方法。

问题1:哪些是JVM管理的?哪些是操作系统管理的?

上面这些状态全是由JVM管理的,因为JVM管理的时候也要通过操作系统,所以呢,那个是操作系统和那个是JVM他俩分不开,JVM是跑在操作系统上的一个普通程序 。

问题2:线程什么状态时候会被挂起?挂起是否也是一个状态?

Running的时候,在一个cpu上会跑很多个线程,cpu会隔一段时间执行这个线程一下,在隔一段时间执行那个线程一下,这个是cpu内部的一个调度,把这个状态线程扔出去,从running扔回去就叫线程被挂起,cpu控制它。

来看一下ThraedState这段代码。

package com.mashibing.juc.c_000;
public class T04_ThreadState {static class MyThread extends Thread {@Overridepublic void run() {System.out.println(this.getState());for(int i=0; i<10; i++) {try {Thread.sleep(500);} catch (InterruptedException e) { e.printStackTrace();}System.out.println(i);}}}public static void main(String[] args) {Thread t = new MyThread();//怎么样得到这个线程的状态呢?就是通过getState()这个方法System.out.println(t.getState());//他是一个new状态t.start();//到这start完了之后呢是Runnable的状态try {t.join();} catch (InterruptedException e) { e.printStackTrace();}//然后join之后,结束了是一个Timenated状态System.out.println(t.getState());}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34050.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CentOS 7 64 安装 Docker

前言 在虚拟机中安装 Docker 是一种常见的测试和开发环境搭建方式。通过在虚拟机上安装 Docker&#xff0c;可以方便地创建和管理容器化应用&#xff0c;同时避免对宿主机系统造成影响。以下是在 CentOS 7 虚拟机中安装 Docker 的详细步骤。 1. 更新系统&#xff08;可以不操作…

SPI驱动(八) -- SPI_DAC设备驱动程序

文章目录 参考资料&#xff1a;一、编写设备树二、 编写驱动程序三、编写测试APP四、Makefile五、上机实验 参考资料&#xff1a; 参考资料&#xff1a; 内核头文件&#xff1a;include\linux\spi\spi.h内核文档&#xff1a;Documentation\spi\spidevDAC芯片手册&#xff1a;…

Ansible 自动化运维

Ansible架构: 一.部署主机清单 前期环境准备: 管理端: 192.168.60.128 被管理端: client1:192.168.60.129 client2:192.168.60.131 1.所有被管理端配置ssh密钥 (1.免密登陆 2.允许root远程登陆) 脚本如下: #!/bin/bash# 检查 sshpass 是否已安装 if ! command -v ss…

Qt 实现波浪填充的圆形进度显示

话不多说&#xff0c;先上效果图 代码示例&#xff1a; #include <QApplication> #include <QWidget> #include <QPainter> #include <QPropertyAnimation> #include <QTimer> #include <cmath>class WaveProgressBar : public QWidget {…

DQN 玩 2048 实战|第一期!搭建游戏环境(附 PyGame 可视化源码)

视频讲解&#xff1a; DQN 玩 2048 实战&#xff5c;第一期&#xff01;搭建游戏环境&#xff08;附 PyGame 可视化源码&#xff09; 代码仓库&#xff1a;GitHub - LitchiCheng/DRL-learning: 深度强化学习 2048游戏介绍&#xff0c;引用维基百科 《2048》在44的网格上进行。…

星越L_外后视镜使用讲解

目录 1.外后视镜调节 2后视镜折叠 3.后视镜加热 1.外后视镜调节 L控制左边后视镜调节,上下拨动调整视野,一般此镜左右21分,上下55开。 R控制左边后视镜调节,上下拨动调整视野,一般此镜左右13分,上下55开。 2后视镜折叠 车辆解锁自动展开 车辆关闭自动折叠 严寒天气…

2025-03-15 Python深度学习2——Numpy库

文章目录 1 基础1.1 数据类型1.1.1 整型数组与浮点型数组1.1.2 元素同化1.1.3 数组类型转换 1.2 数组维度1.2.1 一维数组与二维数组1.2.2 数组形状变换 2 创建数组2.1 创建指定数组2.2 创建递增数组2.3 创建同值数组2.4 创建随机数组 3 索引3.1 访问数组元素3.1.1 访问向量3.1.…

【Linux-传输层协议TCP】流量控制+滑动窗口+拥塞控制+延迟应答+捎带应答+面向字节流+粘包问题+TCP异常情况+TCP小结

5.流量控制 接收端处理数据的速度是有限的。如果发送端发的太快&#xff0c;导致接收端的缓冲区被打满&#xff0c;这个时候如果发送端继续发送就会造成丢包&#xff0c;继而引起丢包重传等等一系列连锁反应。 因此TCP 支持根据接收端的接收数据的能力来决定发送端发送数据的…

[C语言日寄] qsort函数的练习

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…

C语言每日一练——day_8

引言 针对初学者&#xff0c;每日练习几个题&#xff0c;快速上手C语言。第八天。&#xff08;连续更新中&#xff09; 采用在线OJ的形式 什么是在线OJ&#xff1f; 在线判题系统&#xff08;英语&#xff1a;Online Judge&#xff0c;缩写OJ&#xff09;是一种在编程竞赛中用…

python从邮件中提取链接中的符号为什么会变成amp; 解决办法

在Python中&#xff0c;从邮件中提取链接时&#xff0c;&符号变成&amp;是因为HTML实体编码。HTML使用&amp;表示&&#xff0c;以确保在浏览器中正确显示。 原因 HTML实体编码&#xff1a;&在HTML中有特殊含义&#xff0c;用于表示实体编码的开始。为了避免…

农业电商|基于SprinBoot+vue的农业电商服务系统(源码+数据库+文档)

农业电商服务系统 目录 基于SprinBootvue的农业电商服务系统 一、前言 二、系统设计 三、系统功能设计 5.1系统功能实现 5.2后台模块实现 5.2.1管理员模块实现 5.2.2商家模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码…

【JAVA】七、基础知识“if+switch+循环结构”详细讲解~简单易懂!

目录 7、逻辑控制 7.1 分支结构 7.1.1 if 语句 语法格式1 语法格式2 语法格式3 7.1.2 switch语句 基本语法 执行流程 7.2 循环结构 7.2.1 while循环 语法格式 7.2.2 Break 7.2.3 Continue 7.2.4 for循环 语法格式 执行过程 7.2.5 do while循环 语法格式 7.3 …

C# Exe + Web 自动化 (BitComet 绿灯 自动化配置、设置)

BitComet GreenLight,内网黄灯转绿灯 (HighID), 增加p2p连接率提速下载-CSDN博客 前两天写个这个&#xff0c;每次开机关机后要重来一遍很麻烦的索性写个自动化。 先还是按照上面的教程自己制作一遍&#xff0c;留下Luck 以及 路由器相关的 端口记录信息。 &#xff08;因为自…

JumpServer基础功能介绍演示

堡垒机可以让运维人员通过统一的平台对设备进行维护&#xff0c;集中的进行权限的管理&#xff0c;同时也会对每个操作进行记录&#xff0c;方便后期的溯源和审查&#xff0c;JumpServer是由飞致云推出的开源堡垒机&#xff0c;通过简单的安装配置即可投入使用&#xff0c;本文…

sqldef:一款免费的数据库变更管理工具

应用程序的升级通常伴随着数据库表结构的变更&#xff0c;为了维护各种环境的数据库变更&#xff0c;我们通常需要引入 Liquibase 或者 Flyaway 这样的数据库版本控制工具。不过&#xff0c;这类工具通常需要绑定某种编程语言&#xff0c;例如 Java&#xff1b;这次我们介绍一个…

行为模式---状态模式

概念 状态模式是一种行为模式&#xff0c;用于在内部状态改变的时候改变其行为。它的核心思想就是允许一个对象在其内部状态改变的时候改变它的行为。状态模式通过将对象的状态封装成独立的类&#xff0c;并将其行为委托给当前的状态对象&#xff0c;从而使得对象行为随着状态…

1688按图搜索商品(拍立淘)接口的参数说明【附代码实例】

阿里巴巴中国站按图搜索1688商品&#xff08;拍立淘&#xff09; API 返回值说明 item_search_img-按图搜索1688商品&#xff08;拍立淘&#xff09; 1688.item_search_img 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;se…

Linux文件管理练习

1、列出所有账号的账号名 切割显示-cut 作用&#xff1a;cut命令用于按列提取文本内容 格式: cut -d "分隔符" -f列数字 文件名 2、将/etc/passwd中内容按照冒号隔开的第三个字符从大到小排序后输出所有内容 排序显示-sort 作用:sort命令用于对文本内容进行排…

解决PC串流至IPad Pro时由于分辨率不一致导致的黑边问题和鼠标滚轮反转问题

问题背景 今天在做 电脑串流ipad pro 的时候发现了2个问题&#xff1a; 1.ipadpro 接上鼠标后&#xff0c;滚轮上下反转&#xff0c;这个是苹果自己的模拟造成的问题&#xff0c;在设置里选择“触控板与鼠标”。 关闭“自然滚动”,就可以让鼠标滚轮正向滚动。 2. ipadpro 分…