首页IT科技多线程高并发问题(【多线程与高并发】- 线程基础与状态)

多线程高并发问题(【多线程与高并发】- 线程基础与状态)

时间2025-07-29 10:33:44分类IT科技浏览4839
导读:线程基础与状态 ?生命不息,写作不止...

线程基础与状态

?生命不息               ,写作不止

? 继续踏上学习之路                     ,学之分享笔记

? 总有一天我也能像各位大佬一样

? 一个有梦有戏的人 @怒放吧德德

?分享学习心得       ,欢迎指正               ,大家一起学习成长!

前言

好久没坚持学习了                     ,所以       ,这次要好好下定决心学习               。多线程与高并发不是一天两天就能弄懂的        ,需要不断的学习               、实践                     ,本次笔者将最近学习的内容知识记录下来                     。多线程也是一项比较重要的内容              ,虽然CRUD不太会接触到        ,但是                      ,在一些相关场景可能会有某些问题是由于线程导致的       。

线程的概念

要了解线程的概念              ,就需要知道什么是进程               。简单理解就是一个进程中包含了许多个线程                     。现在就简单介绍,后续若是有对操作系统进行研究的话会慢慢介绍                      ,具体关于线程进程的内容可以去看看王道的操作系统                     ,里面讲述得特别清楚       。

什么是进程?

是系统进行资源分配的基本单位,是操作系统结构的基础               ,进程是线程的容器        。程序是指令                     、数据及其组织形式的描述                     ,进程是程序的实体                     。

什么是线程?

所谓线程就是操作系统(OS)能够进行运算调度的最小单位       ,是一个基本的CPU执行单元               ,也是执行程序流的最小单元              。能够提高OS的并发性能                     ,减小程序在并发执行时所付出的时空开销        。线程是进程的一个实体       ,是被系统独立调度和分派的基本单位                      。线程本身是不拥有系统资源的        ,但是它能够使用同属进程的其他线程共享进程所拥有的全部资源              。

在Java线程中是怎样的呢?

在Java中                     ,最常见得就是继承Thread类或者实现Runnable接口              ,再通过run或者start方法去执行线程。

如以下代码        ,这是一段很简单得代码块                      ,通过继承Thread类              ,重写run方法来创建线程,并且通过run和start来运行                      。 public class Thread_demo01 { private static class Thread1 extends Thread { @Override public void run() { for (int i = 0; i < 5; i++) { try { Thread.sleep(1); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("Thread1-" + i); } } } public static void main(String[] args) { new Thread1().run(); // 顺序执行 // new Thread1().start(); // 线程同时执行 for (int i = 0; i < 5; i++) { try { Thread.sleep(1); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("main"); } } }

这两种不同得启动方式                      ,出现得现象也是不同的                     。

使用run方法启动线程

使用start方法启动线程

关于这两种方式启动线程可以看一下下面的流程图。

run方法是会让线程T1先执行完毕之后                     ,再继续执行主线程,而start方法他是同时执行两个线程               。

Java线程的Sleep       、Yield               、Join方法

1                     、sleep方法

sleep()需要提供一个时间参数(毫秒)               ,会使得线程在一定的时间内被暂停执行                     ,在sleep的过程中       ,线程是不会释放锁的               ,只会进入阻塞状态                     ,让出cpu给其他线程去执行                     。如下代码演示       ,此处不做锁的探究       。

public class T3_Thread_Sleep { public static void main(String[] args) { Thread t1 = new Thread(new Thread1()); Thread t2 = new Thread(new Thread2()); t1.start(); t2.start(); } static class Thread1 implements Runnable { @Override public void run() { System.out.println("T1 is running"); try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("T1 is end"); } } static class Thread2 implements Runnable { @Override public void run() { System.out.println("T2 is running"); try { Thread.sleep(2000); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("T2 is end"); } } }

运行之后在T1线程休眠的时候会让出cpu资源给T2线程        ,T1线程会睡眠1秒                     ,T2睡眠2秒              ,最终结果如图

2       、Yield方法

yield()与sleep()都是让线程暂停执行        ,也是不会释放锁资源               。但是yield并不是让进程进入阻塞态                      ,而是回到就绪态              ,等待重新获取CPU资源                     。此时,其他的线程有机会获得cpu资源                      ,也有可能在yield方法进入就绪态后立马变成执行态       。如以下代码                     ,同样不考虑锁的问题        。

public class T4_Thread_Yield { static class Thread1 implements Runnable { @Override public void run() { System.out.println("T1 is running"); Thread.yield(); System.out.println("T1 is end"); } } static class Thread2 implements Runnable { @Override public void run() { System.out.println("T2 is running"); System.out.println("T2 is end"); } } public static void main(String[] args) { Thread t1 = new Thread(new Thread1()); Thread t2 = new Thread(new Thread2()); t1.start(); t2.start(); } }

经过不同的测试,结果都是不同的                     。

3        、Join方法

join()方法是暂停当前线程               ,调用执行另一个线程                     ,等待join的线程执行完毕后才能够继续执行当前线程              。如以下例子       ,T1,T2同时开始               ,在T2线程中join了T1                     ,就会导致T1要先执行完毕之后       ,才会去执行T2        。

public class T5_Thread_Join { public static void main(String[] args) { Thread T1 = new Thread(() -> { System.out.println("T1开始"); for (int i = 0; i < 5; i++) { System.out.println("线程T1执行中: " + i); } System.out.println("T1结束"); }); Thread T2 = new Thread(() -> { System.out.println("T2开始"); for (int i = 0; i < 5; i++) { System.out.println("线程T2执行中: " + i); if (i == 3) { try { T1.join(); } catch (InterruptedException e) { throw new RuntimeException(e); } } } System.out.println("T2结束"); }); T1.start(); T2.start(); } }

结果如下        ,不管怎么测试                     ,都会是T2最后执行结束                      。

Java的线程状态

线程具有最基本的三态(就绪                     、运行              、阻塞)              。线程与进程一样              ,各线程之间也存着共享资源和互相合作的制约关系        ,致使线程运行时具有间断性。接下来看一下如图                      ,这是五种状态的转化                      。

线程的不同状态

在Java线程中有6中状态              ,从线程的创建到线程的终止                     。线程创建为NEW创建态,通过start启动线程                      ,线程内部会从就绪态转成运行态                     ,在Java线程中统称为“运行态               ”,线程由于被挂起        、调用yeild等方法能够使线程从运行态转成就绪态               ,也能够通过线程的其他方法或者锁阻塞线程                     ,直到时间结束或者是获得锁等       ,从而回到RUNABLE状态。

初始(NEW):新创建了一个线程对象               ,但还没有调用start()方法               。 运行(RUNNABLE):Java线程中将就绪(Ready)和运行中(Running)两种状态笼统的称为“运行                     ”                     。线程对象创建后                     ,其他线程(比如main线程)调用了该对象的start()方法       。该状态的线程位于可运行线程池中       ,等待被线程调度选中        ,获取CPU的使用权                     ,此时处于就绪状态(Ready)               。就绪状态的线程在获得CPU时间片后变为运行中状态(Running)                     。 阻塞(BLOCKED):表示线程阻塞于锁       。 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)        。 超时等待(TIMED_WAITING):该状态不同于WAITING              ,它可以在指定的时间后自行返回                     。 终止(TERMINATED):表示该线程已经执行完毕              。

Java线程的状态转化

如线程状态转换图        ,以下就是Java线程状态的转换流程        。线程可以通过实现Runnable接口或者继承Threa类                      ,然后去实例化Java的线程对象                      。在线程被执行之前都是属于创建态(NEW)              ,在调用start方法后,线程就会转成RUNABLE状态                      ,在RUNABLE中                     ,当线程处于就绪态(Ready)的时候,经过调度分配了cpu资源               ,这时转成了运行态                     ,当线程被挂起                      、线程执行了yield       ,线程将会退回就绪态              。在运行态(RUNABLE)               ,也会通过一些处理而被阻塞或者等待。终止状态(TERMINATED)是线程执行完毕退出                     ,此时       ,终止态的线程不会直接转成创建态                      。

Java线程状态代码

Java中线程的状态都是在java.lang.Thread.State

的枚举类中                     。

可以看一下以下枚举代码        ,分别为(NEW              、RUNNABLE、BLOCKED                      、WAITING                     、TIMED_WAITING、TERMINATED)六种。 public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; }

接下来看一下演示代码

public class T6_Thread_State { static class Thread1 extends Thread { @Override public void run() { System.out.println("run - 当前线程的状态: " + this.getState()); for (int i = 0; i < 5; i++) { try { System.out.println("sleep前 - 当前线程的状态: " + this.getState()); Thread.sleep(1000); System.out.println("sleep后 - 当前线程的状态: " + this.getState()); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } public static void main(String[] args) throws InterruptedException { Thread1 t1 = new Thread1(); System.out.println("main - 当前线程的状态: " + t1.getState()); t1.start(); System.out.println("join前 - 当前线程的状态: " + t1.getState()); t1.join(); System.out.println("join后 - 当前线程的状态: " + t1.getState()); } }

运行结果                     ,可以只管看到线程在运行过程种的状态切换               。

博文推荐

这里推荐给各位一篇很不错的博客文章              ,是针对Java线程的状态转换的详细介绍

Java线程的6种状态及切换(透彻讲解)_潘建南的博客-CSDN博客_线程的5种状态

线程池 waiting on condition_Java线程生命周期与状态切换_有所不知的博客-CSDN博客

?创作不易        ,如有错误请指正                      ,感谢观看!记得点赞哦!?

声明:本站所有文章              ,如无特殊说明或标注,均为本站原创发布                     。任何个人或组织                      ,在未征得本站同意时                     ,禁止复制               、盗用                     、采集       、发布本站内容到任何网站               、书籍等各类媒体平台       。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理               。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
指定的网络名不再可用怎么解决win7(指定的网络名不再可用介绍) typeblog(Typecho:开源轻量级博客平台,打造个性化的网络内容)