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

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线程面试题(50)

不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题。Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大多数待遇丰厚的Java开发职位都要求开发者精通多线程技术并且有丰富的Java程序开发、调试、优化经验,所以线程相关的问题在面试中经常会被提到。 在典型的Java面试中, 面试官会从线程的基本概念问起, 如:为什么你需要使用线程,

线程池ThreadPoolExecutor类源码分析

Java并发编程:线程池的使用   在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:   如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。   那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?

线程Lock

线程Lock   在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问。本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式来实现同步访问,那就是Lock。   也许有朋友会问,既然都可以通过synchronized来实现同步访问了,那么为什么还需要提供Lock?这个问题将在下面进行阐述。本文先从s

线程封装,互斥

文章目录 线程封装线程互斥加锁、解锁认识接口解决问题理解锁 线程封装 C/C++代码混编引起的问题 此处pthread_create函数要求传入参数为void * func(void * )类型,按理来说ThreadRoutine满足,但是 这是在内类完成封装,所以ThreadRoutine函数实际是两个参数,第一个参数Thread* this不显示 解决方法: 第

Linux-笔记 线程同步机制

目录 前言 实现 信号量(Semaphore) 计数型信号量 二值信号量  信号量的原语操作 无名信号量的操作函数 例子 互斥锁(mutex) 互斥锁的操作函数 例子 自旋锁 (Spinlock) 自旋锁与互斥锁的区别 自旋锁的操作函数 例子 前言         线程同步是为了对共享资源的访问进行保护,确保数据的一致性,由于进程中会有多个线程的存在,

jmeter之Thread Group(线程组)

Thread Group(线程组) 1.线程组,或者可以叫用户组,进行性能测试时的用户资源池。 2.是任何一个测试计划执行的开始点。 3.上一篇提到的“控制器”和“HTTP请求”(采集器)必须在线程组内;监听器等其他组件,可以直接放在测试计划下。 线程组设置参数的意义 我们以下图为例,进行详细说明。见下图:  区域1(在取样器错误后要执行的动作) 这个区域的主要作用很明显,在线程内

如何在Android中实现多线程与线程池?

目录 一、Android介绍二、什么是多线程三、什么是线程池四、如何在Android中实现多线程与线程池 一、Android介绍 Android是一种基于Linux内核的开源操作系统,由Google公司领导开发。它最初于2007年发布,旨在为移动设备提供一种统一、可扩展的操作系统。Android系统以其高度的可定制性和丰富的应用生态而受到广泛欢迎,如今已经成为全球最流行的

线程间通信方式(互斥(互斥锁)与同步(无名信号量、条件变量))

1通信机制:互斥与同步 线程的互斥通过线程的互斥锁完成; 线程的同步通过无名信号量或者条件变量完成。 2  互斥 2.1 何为互斥?         互斥是在多个线程在访问同一个全局变量的时候,先让这个线程争抢锁的资源,那个线程争抢到资源,它可以访问这个变量,没有争抢到资源的线程不能够访问这个变量。那这种只有一个线程能够访问到这个变量的现象称之为线程间互斥。 2.2互斥锁API 1.

程序人生:关于RHCE红帽认证这件事

花了两个月备考红帽,最终终于双满分通过。  关于考试 RHCE红帽认证总共需要考两门:RHCSA、RHCE。 RHCSA主要是考察基本的Linux操作:用户、权限、空间扩容、yum、容器等内容。 RHCE主要是考察ansible playbook 代码的开发。 通过考试没有别的捷径,就是敲命令,键盘照着冒烟了敲。 关于备考        说是两个月时间备考,其实前面一个