人生只若如初见——初见线程

2024-03-10 10:50
文章标签 线程 如初 人生 初见

本文主要是介绍人生只若如初见——初见线程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

之前在学习多线程的时候,那个时候并没有掌握得很好,用一句话来形容就是“略懂一二”。近段时间,又重温了多线程,我却发现,多线程的内容涉及甚广,不仅仅针对单一程序,而且还涉及有关系统的性能等方面,今天决定重新来了解它,都说“人生只若如初见”,总觉得初见的时候我们是最好的,至此,已初见的态度重新学习多线程。

谈到线程,首先还是得从一些基本只是开始——————

线程和多线程

线程

所谓线程,使用官方的语言来说,能共享代码和数据空间的同一类程序,使用我自己的话来说,线程就如同一个系统中牵引着多个程序同时进行的“线”,(可能比喻得不太恰当,如谁有更形象的比喻,还请指正!),但是我们知道每个线程都有自己独立的的栈和程序计数器(PC),线程之间的切换开销相对于进程来说还是比较小的。那么,进程又是什么?没学过操作系统的人,可能不理解,其实,进程和线程如同双胞胎兄弟,从字面上区别,进程是指正在运行的程序,而线程范围似乎又包括进程,可是实质不以为然,进程可以是多种不同的程序。而线程是指同一类的程序,每一个进程都共享代码和数据空间,而线程是同一类线程共享代码和数据空间。从操作系统的角度来看,线程是CPU调度的最小单位,而进程是资源调度的最小单位。

多线程

那么多线程是什么呢?从字面上看,是多个线程共同运行的状态,其实,这里强调的是多个线程同时并发的状态,而我们所面临的就是如何去解决这并发的问题,要想探究得深入,那么首先,多线程必须理解得非常的得透彻。

理解

在了解线程是什么之后,需要明白一点,我们为什么要选择使用线程?很多人看来,使用线程能更大得提高效率,当然,也不能否认这点,多线程环境下,确实能够很大程度提高效率,但是凡事有利也有弊,有些时候,由于多线程创建和销毁过程是特别消耗内存的,因此这种情况下,效率不能提高反而降低性能。因此,对于多线程的使用,需要大量的经验来让我们学会如何掌控它。

线程的几种状态以及状态切换

线程状态是线程控制的基础。要想更好的掌握如何适当得使用线程,那么其几个状态必须要掌握的,这也是线程的生命周期。
如图所示:
线程的五个状态

线程定义的三种方式

继承Thread类

这种定义线程的方式是最简单的,但是一般不推荐。那这又是为什么呢?其实,这要看类与类之间的继承特点,我们应该都知道,类之间的继承属于单继承,而在以后的编码开发过程中,不能保证每一个类不能拥有父类,这样看来,如果再想使用继承Thread类的方式来定义线程,那么这样是行不通的。但是这种方式还是需要了解的,以下有个示例来让大家更好的理解。

/*** 实现线程的方式一,继承Thread类* Created by Cecilia on 2017/7/26.*/
public class ThreadDemo extends Thread{@Overridepublic  void run(){for (int cnt=1;cnt<100;cnt++){try {System.out.println("线程1计数:"+cnt);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}public static void main(String[] args) {//第一种定义线程的方式ThreadDemo td = new ThreadDemo();td.start();}

实现Runnable接口

实现Runnable接口的方式虽然在开启线程的过程中代码比较复杂,但是这种方式一般对于没有返回值的线程而言是最好的选择。因为接口具有多继承的特点,凭借这优点,在程序员定义线程时会优先选择这种方式。同样的,提供一个例子,让其更好地去理解。

/*** 实现线程的方式二,实现Runnable接口* Created by Cecilia on 2017/7/26.*/
public class RunnableDemo implements Runnable{@Overridepublic  void run(){for (int cnt=1;cnt<100;cnt++){try {System.out.println("线程2计数:"+cnt);Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}public static void main(String[] args) {//第二种定义线程的方式RunnableDemo rd = new RunnableDemo();Thread thread = new Thread(rd);thread.start();}

实现Callable接口(带有返回值的线程)

前面两种方式是最常见的,但是对于大数据开发者来说,有很多场景是需要带有返回值的多线程,比如爬虫,这些需要将数据存储在Mon共DB中,同时需要利用多线程来使其爬取效率比较高。当然,以一个例子来让其看下这种定义方式。在开启线程时,需要使用Future工具类来帮助开启。

/*** 第三种定义线程方式:实现带有返回值的线程接口(JDK1.5以后)* Created by Cecilia on 2017/7/26.*/
public class CallableDemo implements Callable<String>{@Overridepublic String call() throws Exception {//Thread.sleep(1000);//Sleep能不用就不用,可以使用TimeUnitTimeUnit.MILLISECONDS.sleep(1000);String message = "This is another message!";return message;}
}public static void main(String[] args) {//第三种定义线程方式CallableDemo callableDemo = new CallableDemo();FutureTask<String> futureTask = new FutureTask<>(callableDemo);Thread thread1 = new Thread(futureTask);thread1.start();while(true){if (futureTask.isDone()){                         //判断线程是否执行结束try {System.out.println(futureTask.get());     //获取返回值,线程阻塞} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}finally {break;}}else{try {TimeUnit.MILLISECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}}}}

这篇关于人生只若如初见——初见线程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/794001

相关文章

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

Java终止正在运行的线程的三种方法

《Java终止正在运行的线程的三种方法》停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作,停止一个线程可以用Thread.stop()方法,但最好不要用它,本文给大家介绍了... 目录前言1. 停止不了的线程2. 判断线程是否停止状态3. 能停止的线程–异常法4. 在沉睡中停止5

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线

在 Spring Boot 中使用异步线程时的 HttpServletRequest 复用问题记录

《在SpringBoot中使用异步线程时的HttpServletRequest复用问题记录》文章讨论了在SpringBoot中使用异步线程时,由于HttpServletRequest复用导致... 目录一、问题描述:异步线程操作导致请求复用时 Cookie 解析失败1. 场景背景2. 问题根源二、问题详细分

Java多线程父线程向子线程传值问题及解决

《Java多线程父线程向子线程传值问题及解决》文章总结了5种解决父子之间数据传递困扰的解决方案,包括ThreadLocal+TaskDecorator、UserUtils、CustomTaskDeco... 目录1 背景2 ThreadLocal+TaskDecorator3 RequestContextH

java父子线程之间实现共享传递数据

《java父子线程之间实现共享传递数据》本文介绍了Java中父子线程间共享传递数据的几种方法,包括ThreadLocal变量、并发集合和内存队列或消息队列,并提醒注意并发安全问题... 目录通过 ThreadLocal 变量共享数据通过并发集合共享数据通过内存队列或消息队列共享数据注意并发安全问题总结在 J

异步线程traceId如何实现传递

《异步线程traceId如何实现传递》文章介绍了如何在异步请求中传递traceId,通过重写ThreadPoolTaskExecutor的方法和实现TaskDecorator接口来增强线程池,确保异步... 目录前言重写ThreadPoolTaskExecutor中方法线程池增强总结前言在日常问题排查中,

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

C语言线程池的常见实现方式详解

《C语言线程池的常见实现方式详解》本文介绍了如何使用C语言实现一个基本的线程池,线程池的实现包括工作线程、任务队列、任务调度、线程池的初始化、任务添加、销毁等步骤,感兴趣的朋友跟随小编一起看看吧... 目录1. 线程池的基本结构2. 线程池的实现步骤3. 线程池的核心数据结构4. 线程池的详细实现4.1 初