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

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

相关文章

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 初

Java子线程无法获取Attributes的解决方法(最新推荐)

《Java子线程无法获取Attributes的解决方法(最新推荐)》在Java多线程编程中,子线程无法直接获取主线程设置的Attributes是一个常见问题,本文探讨了这一问题的原因,并提供了两种解决... 目录一、问题原因二、解决方案1. 直接传递数据2. 使用ThreadLocal(适用于线程独立数据)

线程的四种操作

所属专栏:Java学习        1. 线程的开启 start和run的区别: run:描述了线程要执行的任务,也可以称为线程的入口 start:调用系统函数,真正的在系统内核中创建线程(创建PCB,加入到链表中),此处的start会根据不同的系统,分别调用不同的api,创建好之后的线程,再单独去执行run(所以说,start的本质是调用系统api,系统的api

java线程深度解析(六)——线程池技术

http://blog.csdn.net/Daybreak1209/article/details/51382604 一种最为简单的线程创建和回收的方法: [html]  view plain copy new Thread(new Runnable(){                @Override               public voi

java线程深度解析(五)——并发模型(生产者-消费者)

http://blog.csdn.net/Daybreak1209/article/details/51378055 三、生产者-消费者模式     在经典的多线程模式中,生产者-消费者为多线程间协作提供了良好的解决方案。基本原理是两类线程,即若干个生产者和若干个消费者,生产者负责提交用户请求任务(到内存缓冲区),消费者线程负责处理任务(从内存缓冲区中取任务进行处理),两类线程之

java线程深度解析(四)——并发模型(Master-Worker)

http://blog.csdn.net/daybreak1209/article/details/51372929 二、Master-worker ——分而治之      Master-worker常用的并行模式之一,核心思想是由两个进程协作工作,master负责接收和分配任务,worker负责处理任务,并把处理结果返回给Master进程,由Master进行汇总,返回给客