Java多线程的使用

无论在我们的工作中还是在我们的生活中,我们都会用到多线程的知识,今天就给大家讲一下如何使用多线程。

序幕

线程的启动
如何使线程暂停
如何使线程停止
线程的优先级
线程安全相关的问题

我们首先要知道进程和线程分别是什么?

进程 - 进程是具有一定独立功能的程序(例如QQ.exe),关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

线程 - 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位;线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。

一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。

相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

在串行程序基础上引入线程和进程是为了提高程序的并发度,从而提高程序运行效率和响应时间。

多线程的优点
多线程从某方面来说等价于多任务,当你有多个任务要处理时,多个任务一起做所消耗的时间肯定比任务串行起来做,所消耗的时间短;

如图所示
在这里插入图片描述

多线程的使用

在Java的JDK包中,已经自带了对多线程技术的支持,可以非常方便地进行多线程的编程。实现多线程编程的方式主要有两种:

继承Thread类

实现Runnable接口

如图所示
在这里插入图片描述
Thread类实现了Runnable接口,它们之间具有多态关系。

Runnable接口类

@FunctionalInterface
public interface Runnable {public abstract void run();
}

Thread类主要源码:

public class Thread implements Runnable {public static native Thread currentThread();public static native void yield();public static native void sleep(long millis) throws InterruptedException;public static void sleep(long millis, int nanos) throws InterruptedException {// ...sleep(millis);}public Thread() {init(null, null, "Thread-" + nextThreadNum(), 0);}public Thread(Runnable target) {init(null, target, "Thread-" + nextThreadNum(), 0);}public Thread(ThreadGroup group, Runnable target) {init(group, target, "Thread-" + nextThreadNum(), 0);}public synchronized void start() {// ...start0(); // ...}private native void start0();@Deprecatedpublic final void stop() {// ...}public void interrupt() {// ...}public static boolean interrupted() {return currentThread().isInterrupted(true);}public boolean isInterrupted() {return isInterrupted(false);}private native boolean isInterrupted(boolean ClearInterrupted);public final native boolean isAlive();@Deprecatedpublic final void suspend() {checkAccess();suspend0();}@Deprecatedpublic final void resume() {checkAccess();resume0();}
}

这二种创建线程的方式有什么区别?
Java类是单继承的,而接口可以支持多继承,使用Thread类的方式创建新线程时,最大的局限就是不支持多继承。所以具体选择哪种方式来创建线程,就看你是不是需要具体多继承的特性。

Thread详解

看到Thread的源码,我们现在对其主要的的一些方法进行讲解一下
native关键字 - native是与C++联合开发的时候用的!使用native关键字说明这个方法是原生函数,也就是说这个方法是用C/C++语言实现的,并且被编译成dll相关组件,由java来调用。所以从上面的Thread类源代码中可以看到,有好多是调用了原生的函数。

构造方法 - Thread有一组构造方法,具体指定了线程名称(name)、线程组(ThreadGroup)、接口类(Runnable)、栈大小(stackSize)等参数 具体如下:

public Thread()
public Thread(Runnable target)
Thread(Runnable target, AccessControlContext acc)
public Thread(ThreadGroup group, Runnable target)
public Thread(String name)
public Thread(ThreadGroup group, String name)
public Thread(Runnable target, String name)
public Thread(ThreadGroup group, Runnable target, String name)
public Thread(ThreadGroup group, Runnable target, String name, long stackSize)

isAlive() - 方法isAlive()是判断当前的线程是否处于活动状态。而这个活动状态指的是:线程已经启动且尚未终止,如正在运行,准备开始运行的状态,都认为线程是“存活”的。

sleep() - 在指定的毫秒数内让当前“正在执行的线程”休眠(暂停执行)。这个“正在执行的线程”是指this.currentThread()返回的线程。

getId() - 取得线程的唯一标识。每个线程在初始化的过程中都会调用nextThreadID方法获取到一个唯一标识。

private static long threadSeqNumber;
private static synchronized long nextThreadID() {return ++threadSeqNumber;
} 

在一个进程中,线程的ID是唯一。

停止线程 - 停止线程是在多线程开始时很重要的技术点,而停止线程在Java中并不像break语句那样干脆,需要一些技巧性的处理。

在Java中有以下3种方法可以终止正在运行的线程。

1.使用退出标志,使线程正常退出,即当run方法完成后线程终止。

2.使用stop方法强行终止线程,但是不推荐使用该方法,因为stop和suspend及resume一样,都是作废过期的方法,使用它们可能产生不可预料的结果。

3.使用interrupt方法中断线程。

暂停线程 - 暂停线程意味着此线程还可以恢复运行。使用suspend()方法暂停线程,resume()方法恢复线程的执行。
yield - yield()方法的作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间。但是放弃的时间不确定,有可能刚放弃,马上又获得CPU时间片了。

线程优先级 - 在操作系统中,线程可以划分优先级,优先级较高的线程得到的CPU资料较多,也就是CPU优先执行优先级较高的线程对象中的任务。在Thread中,我们使用setPriority()方法设置优先级别。

java的线程优先级分为1~10这10个等级

public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;

线程优先级的三个特性

线程优先级具有继承特性, 比如A线程启动B线程,则B线程的优先级与A是一样的。

优先级具有规则性,虽然我们使用setPriority()方法设置了优先级,但是真正执行的过程中,不会保证优先级高的线程绝对比优先级低的线程优先完成。即CPU尽量将执行资源让给优先级比较高的线程。

*优先级具有随机性,具优先级较高的线程不一定每一次都先执行完。

守护线程 - 在Java线程中有两种线程,一种是用户线程,另一种是守护线程。
守护线程是一种特殊的线程,它的特性有“陪伴”的含义,当进程中不存在非守护线程了,则守护线程自动销毁。

典型的守护线程就是垃圾回收线程,当进程中没有非守护线程了,则垃圾回收线程则没有存在的必要了,自动销毁。

只要当前JVM实例中存在任何一个非守护线程没有结束,守护线程就在工作,只有当最后一个非守护线程结束时,守护线程才随着JVM一同结束工作。
通过调用Thread.setDaemon(true)设置是否为守护线程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/565352.shtml

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

相关文章

oracle 存储过程 db,oracle数据库的存储过程是什么?

oracle数据库的存储过程:一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。存储过程(Stored Procedur…

【OpenCV 例程200篇】230. 特征描述之 LBP 统计直方图

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】230. 特征描述之 LBP 统计直方图 局部二值模式(LBP,Local binary patterns)是一种用来描述图像局部纹理特征的算子,它具有旋转不变性和灰度不变性的优点…

【OpenCV 例程200篇】232. 特征描述之频谱方法

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】232. 纹理特征之频谱方法 4.3 纹理特征之频谱方法 傅里叶谱可以描述图像中的周期性或半周期性二维模式的方向性,因此可以基于傅里叶变换对纹理进行频谱分析。 纹理与图像频谱中的高频分…

java制作oracle程序,Java程序操作Oracle两种方式之简单实现

Java程序操作Oracle两种方式之简单实现1.通过JDBC-ODBC桥连接Oracle数据库(1)创建odbc源,在控制面板->管理工具->数据源(odbc)中添加DSN,比如取名为wangtao,选择一个Service,输入用户名密码,测试连接,若通过说明成功;(注意&…

【OpenCV 例程200篇】233. 区域特征之矩不变量

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】233. 区域特征之矩不变量 4.4 区域特征之矩不变量 矩是概率与统计中的一个概念,是随机变量的一种数字特征。矩函数在图像分析中有着广泛的应用,如模式识别、目标分类、图像编…

【OpenCV 例程200篇】231. 特征描述之灰度共生矩阵(GLCM)

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】231. 特征描述之灰度共生矩阵(GLCM) 4.2.4 灰度共生矩阵(GLCM) 灰度共生矩阵(Gray level co-occurrence matrix,GLCM&#xff…

oracle11 处理器数,11G AWR中%Total CPU与%Busy CPU指标的疑问

ODM FINDING:FROM http://www.os2ora.com/how-to-analyze-awr-report-1/ 推荐 kaya 的这篇文章引用如下:如果关注数据库的性能,那么当拿到一份AWR报告的时候,最想知道的第一件事情可能就是系统资源的利用情况了,而首当其冲的&am…

【OpenCV 例程200篇】237. 基于主成分提取的方向校正(OpenCV)

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】237. 基于主成分提取的方向校正(OpenCV) 主成分分析(Principal Components Analysis,PCA)是一种基于统计的数据降维方法,又称主…

swoole 捕捉php错误,swoole怎么处理错误

在协程编程中可直接使用try/catch处理异常。但必须在协程内捕获,不得跨协程捕获异常。不仅是应用层throw的Exception,底层的一些错误也是可以被捕获的,如function、class、method不存在下面的代码中,try/catch和throw在不同的协程…

【OpenCV 例程200篇】235. 特征提取之主成分分析(sklearn)

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】235. 特征提取之主成分分析(sklearn) 特征提取是指从原始特征中通过数学变换得到一组新的特征,以降低特征维数,消除相关性,减少无用信息…

Linux 进程资源分配,linux 进程管理和内存分配

1、进程相关概念进程:正在运行中的程序内核功用:进程管理、文件系统、网络功能、内存管理、驱动程序、安全功能等Process:运行中的程序的一个副本,是被载入内存的一个指令集合进程 ID(Process ID,PID)号码被用来标记各…

【OpenCV 例程300篇】234. 特征提取之主成分分析(PCA)

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程300篇】234. 特征提取之主成分分析(PCA) 5.1 特征提取的方法 初步获取的图像特征维数通常很大,而且往往包含一定的无关或冗余特征。特征提取是指从原始特征中通过数学变…

Java并发编程基础

线程的简介 什么是线程 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 为什么要使用多线…

【OpenCV 例程200篇】236. 特征提取之主成分分析(OpenCV)

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】236. 特征提取之主成分分析(OpenCV) 文章目录【youcans 的 OpenCV 例程200篇】236. 特征提取之主成分分析(OpenCV)5.2 主成分分析的数学方法5.4 OpenC…

linux 访问共享内存,Linux下的共享内存(03)---通过指针访问共享内存中的数据...

环境:Vmware Workstation;CentOS-6.4-x86_64说明:1、将共享内存挂载至进程:void *shmat(int shmid, const void *shmaddr,int shmflg);参数shmid是要附加的共享内存区标示符。总是把参数shmaddr设为0。参数shmflg可以为SHM_RDON…

Java中锁的使用和实现

首先,我们要了解一个概念,JAVA中的锁到底是什么呢? 锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源。 Lock接口 在Java SE 5之后,并发包中新增了Lock接口&am…

【OpenCV 例程200篇】225. 特征提取之傅里叶描述子

『youcans 的 OpenCV 例程200篇 - 总目录』 【youcans 的 OpenCV 例程200篇】225. 特征提取之傅里叶描述子 目标特征的基本概念 通过图像分割获得多个区域,得到区域内的像素集合或区域边界像素集合。我们把感兴趣的人或物称为目标,目标所处的区域就是目…

【OpenCV 例程300篇】238. OpenCV 中的 Harris 角点检测

『youcans 的 OpenCV 例程300篇 - 总目录』 【youcans 的 OpenCV 例程 300篇】238. OpenCV 中的 Harris 角点检测 角是直线方向的快速变化。角点通常被定义为两条边的交点,或者说角点的邻域应该具有两个不同区域的不同方向的边界。 角是高度有效的特征。角点检测&…

基础线性规划实现(matlab,lingo)

目录 一、本次所需解的问题 二、matlab解题 1)语法 2)数学思维 3)matlab解题 运行结果: 三、lingo解题 lingo解题如下: 运行结果: 最后: 一、本次所需解的问题 需解出下面该线性规划问…

cwntos linux kde桌面,Centos如何安装KDE的桌面

其实KDE其实在初次安装系统的时候就可以选择,我下面是进入系统后的安装方法:第一步:检查KDE首先查看自己是否安装了KDE# yum grouplist在grouplist的输出结果中的“Installed Groups:”部分中,如果你能找到“X Window System”和“…