多线程到底重不重要?

news2025/3/17 0:46:54

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

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

第一个是上天

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

第二个是入地

  • 各种基础算法,各种基础的数据结构
  • 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 {
        @Override
        public void run() {
            System.out.println("Hello MyThread!");
        }
}

    static class MyRun implements Runnable {
        @Override
        public void run() {
            System.out.println("Hello MyRun!");
        }
}
 
     static class MyCall implements Callable<String> {
        @Override
        public 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 {
        @Override
        public 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.coloradmin.cn/o/2316319.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

X86 RouterOS 7.18 设置笔记七:不使用Upnp的映射方法

X86 j4125 4网口小主机折腾笔记五&#xff1a;PVE安装ROS RouterOS X86 RouterOS 7.18 设置笔记一&#xff1a;基础设置 X86 RouterOS 7.18 设置笔记二&#xff1a;网络基础设置(IPV4) X86 RouterOS 7.18 设置笔记三&#xff1a;防火墙设置(IPV4) X86 RouterOS 7.18 设置笔记四…

数字隔离器,如何提升储能系统的安全与效能?

随着全球对光伏、风电等可再生能源需求的持续增长&#xff0c;在全球能源转型的浪潮中&#xff0c;储能技术凭借着可平衡能源供需、提高能源利用效率等优势&#xff0c;已成为实现 “双碳” 目标的核心支撑。据国家能源局公布数据显示&#xff0c;截至2024年底&#xff0c;我国…

基于UniApp + Vue3开发的智能汉字转拼音工具

基于UniApp Vue3开发的智能汉字转拼音工具 项目简介 这是一个基于 UniApp Vue3 开发的智能汉字转拼音工具&#xff0c;前端使用 Vue3 构建界面&#xff0c;后端采用 Classic ASP 提供接口支持&#xff0c;通过 pinyin-pro 库实现精准的中文转拼音功能。本工具支持以下特性&…

PyTorch 深度学习实战(14):Deep Deterministic Policy Gradient (DDPG) 算法

在上一篇文章中&#xff0c;我们介绍了 Proximal Policy Optimization (PPO) 算法&#xff0c;并使用它解决了 CartPole 问题。本文将深入探讨 Deep Deterministic Policy Gradient (DDPG) 算法&#xff0c;这是一种用于连续动作空间的强化学习算法。我们将使用 PyTorch 实现 D…

Angular由一个bug说起之十四:SCSS @import 警告与解决⽅案

SCSS import 警告与解决⽅案 ⚠ 警告信息 在 SCSS 中&#xff0c;使⽤ import 可能会产⽣以下警告&#xff1a; Deprecation Warning: Sass import rules are deprecated and will be removed in Dart Sass 3.0.0. ? 为什么会有这个警告&#xff1f; Sass 官⽅已经废弃 imp…

PyTorch系列教程:基于LSTM构建情感分析模型

情感分析是一种强大的自然语言处理&#xff08;NLP&#xff09;技术&#xff0c;用于确定文本背后的情绪基调。它常用于理解客户对产品或服务的意见和反馈。本文将介绍如何使用PyTorch和长短期记忆网络&#xff08;LSTMs&#xff09;创建一个情感分析管道&#xff0c;LSTMs在处…

SEO新手基础优化三步法

内容概要 在网站优化的初始阶段&#xff0c;新手常因缺乏系统性认知而陷入技术细节的误区。本文以“三步法”为核心框架&#xff0c;系统梳理从关键词定位到内容布局、再到外链构建的完整优化链路。通过拆解搜索引擎工作原理&#xff0c;重点阐明基础操作中容易被忽视的底层逻…

Tcp网络通信的基本流程梳理

先来一张经典的流程图 接下介绍一下大概流程&#xff0c;各个函数的参数大家自己去了解加深一下印象 服务端流程 1.创建套接字&#xff1a;使用 socket 函数创建一个套接字&#xff0c;这个套接字后续会被用于监听客户端的连接请求。 需要注意的是&#xff0c;服务端一般有俩…

PHP函数缺陷详解

无问社区-官网&#xff1a;http://www.wwlib.cn 本期无人投稿&#xff0c;欢迎大家投稿&#xff0c;投稿可获得无问社区AI大模型的使用红包哦&#xff01; 无问社区&#xff1a;网安文章沉浸式免费看&#xff01; 无问AI大模型不懂的问题随意问&#xff01; 全网网安资源智…

深度学习GRU模型原理

一、介绍 门控循环单元&#xff08;Gated Recurrent Unit, GRU&#xff09; 是一种改进的循环神经网络&#xff08;RNN&#xff09;&#xff0c;专为解决传统RNN的长期依赖问题&#xff08;梯度消失/爆炸&#xff09;而设计。其核心是通过门控机制动态控制信息的流动。与LSTM相…

网络空间安全(31)安全巡检

一、定义与目的 定义&#xff1a; 安全巡检是指由专业人员或特定部门负责&#xff0c;对各类设施、设备、环境等进行全面或重点检查&#xff0c;及时发现潜在的安全隐患或问题。 目的&#xff1a; 预防事故发生&#xff1a;通过定期的安全巡检&#xff0c;及时发现并解决潜在的…

基于Python+SQLite实现(Web)验室设备管理系统

实验室设备管理系统 应用背景 为方便实验室进行设备管理&#xff0c;某大学拟开发实验室设备管理系统 来管理所有实验室里的各种设备。系统可实现管理员登录&#xff0c;查看现有的所有设备&#xff0c; 增加设备等功能。 开发环境 Mac OSPyCharm IDEPython3Flask&#xff…

面试系列|蚂蚁金服技术面【2】

今天继续分享一下蚂蚁金服的 Java 后端开发岗位真实社招面经&#xff0c;复盘面试过程中踩过的坑&#xff0c;整理面试过程中提到的知识点&#xff0c;希望能给正在准备面试的你一些参考和启发&#xff0c;希望对你有帮助&#xff0c;愿你能够获得心仪的 offer ! 第一轮面试完…

【JavaEE】网络原理之初识

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

Vscode工具开发Vue+ts项目时vue文件ts语法报错-红波浪线等

Vscode工具开发Vuets项目时vue文件ts语法报错-红波浪线等 解决方案 问题如题描述&#xff0c;主要原因是开发工具使用的代码检查与项目的中的ts不一致导导致&#xff0c;解决办法&#xff0c;修改 vscode 中&#xff0c; 快捷键&#xff1a;command shift p, 输入&#xff…

ROS实践(五)机器人自动导航(robot_navigation)

目录 一、知识点 1. 定位 2. 路径规划 (1)全局路径规划 (2)局部路径规划 3. 避障 二、常用工具和传感器 三、相关功能包 1. move_base(决策规划) 2. amcl(定位) 3. costmap_2d(代价地图) 4. global_planner(全局规划器) 5. local_planner(局部规划器…

【小沐学Web3D】three.js 加载三维模型(React)

文章目录 1、简介1.1 three.js1.2 react.js 2、three.js React结语 1、简介 1.1 three.js Three.js 是一款 webGL&#xff08;3D绘图标准&#xff09;引擎&#xff0c;可以运行于所有支持 webGL 的浏览器。Three.js 封装了 webGL 底层的 API &#xff0c;为我们提供了高级的…

软考教材重点内容 信息安全工程师 第19章 操作系统安全保护

19.1.1 操作系统安全概念 一般来说&#xff0c;操作系统的安全是指满足安全策略要求&#xff0c;具有相应的安全机制及安全功能&#xff0c;符合特定的安全标准&#xff0c;在一定约束条件下&#xff0c;能够抵御常见的网络安全威胁&#xff0c;保障自身的安全运行及资源安全。…

【机器学习】基于t-SNE的MNIST数据集可视化探索

一、前言 在机器学习和数据科学领域&#xff0c;高维数据的可视化是一个极具挑战但又至关重要的问题。高维数据难以直观地理解和分析&#xff0c;而有效的可视化方法能够帮助我们发现数据中的潜在结构、模式和关系。本文以经典的MNIST手写数字数据集为例&#xff0c;探讨如何利…

【Pycharm】Pycharm无法复制粘贴,提示系统剪贴板不可用

我也没有用vim的插件&#xff0c;检查了本地和ubutnu上都没有。区别是我是远程到ubutnu的pycharm&#xff0c;我本地直接控制windowes的pycharm是没问题的。现象是可以从外部复制到pycharm反之则不行。 ctl c ctlv 以及右键 都不行 参考&#xff1a;Pycharm无法复制粘贴&…