当前仍在编辑文章 - Java 并 发 编 程 基 础
Java 并 发 编 程 基 础
1. 概述
在支持同时运行多个任务的系统中,一个任务一般是一个程序,每个程序就是一个进程。而在一个程序其内部,可能包含了多个顺序执行流,每个顺序执行流就是一个线程。
比如在Windows操作系统中,我们可以通过系统自带的任务管理器查看到进程列表。某些进程可以展开,可能会查看到一个或者多个运行的服务或子进程。
1.1 进程与线程
【进程】:进行中的程序。是内存正在执行中的应用程序及其某些必要资源总和,它是线程的容器。
- 程序进行起来他就成了进程
- 一个程序运行起来可能有多个进程:一种情况是,一个应用程序可以启动多个处理进程,所有进程隶属于当前应用程序即所谓的多进程服务。另一种情况是,一个程序只有一个进程,但开启了多个该程序。
进程一般有如下特征:
- 独立性:进程是系统中独立存在的实体。它可以拥有自己独立的资源。每个进行都有总计私有的地址空间。在没有经过进程允许时,一个用于进程不可以直接访问其它进程的地址空间。
- 动态性:程序知识一个静态的指令集合,而进程是一个正在系统中活动的指令集合。进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的。
并发性:多个进程可以在单个处理器上并发执行,且它们之间不会互相影响。
【线程】:线程是位于进程中的执行单元,它是CPU调度的基本单元。
- 线程是操作系统分配CPU时间的基本实体
- 线程是处理器调度的最小单位。
1.2 并发与并行
【并发】:多个任务在CPU上"快速轮换”执行,而实际上任意时刻CPU只能执行其中一个任务。
【并行】:多CPU、多个任务真正同时地在执行。任意时刻多个CUP能同时执行多个任务,即并型才是真正地同时执行任务。
真正并行执行多任务只能在多核CPU上实现。但由于实践中任务数一般远远多余CPU的核心数,因此操作系统会把很多任务的轮流调度到多个核心上执行。对于用户来说,计算机扫描执行一轮又一轮,速度非常之快,直观感觉就像是在并行执行的了。 |
2. Java多线程技术
多线程扩展了多线程地概念,使得同一个进程可以同时并发处理多个任务。已经说过,线程(Thread)也称为轻量级进程(Lightweight Process),是进程地执行单元,而进程是线程地容器。
2.1 线程的生命周期
2.2 创建进程的三种方式
2.2.1 继承Tgread类
(1)继承Thread类,并重写run方法
run()
方法就是线程执行体,即该线程需要完成的事情。
(2)创建Thread子类的实例,并调用strat()
方法期待线程
2.2.2 实现Runnable接口
(1)实现Runnable接口,并重写run()方法;
(2)创建Runnable实现类的实例;
(3)以Runnable实现类的实例为target,创建Thread对象,再调用start方法启动线程。
2.2.3 实现Callable接口
创建Thread子类的实例并调用start()方法启动线程
2.3 多线程编程实例
【实例1】
附录 Thread类
thread是程序中的一个执行线程。Java虚拟机允许应用程序同时运行多个执行线程。
每个线程都有优先级。优先级较高的线程优先于优先级较低的线程执行。每个线程也可以标记为守护进程,也可以不标记。当在某个线程中运行的代码创建一个新的“线程”对象时,新线程的优先级最初被设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时,它才是守护进程。
当一个Java虚拟机启动时,通常有一个非守护线程(它通常调用某个指定类的名为“main”的方法)。Java虚拟机继续执行线程,直到出现以下任一情况:
- 类
Runtime
的exit
方法已被调用,安全管理器已允许退出操作发生。 - 所有不是守护线程的线程都已经死亡,要么是从调用
run
方法返回,要么是抛出一个传播到“运行”方法之外的异常。
有两种方法可以创建新的执行线程。一种是将一个类声明为 Thread
的子类。这个子类应该覆盖类 Thread
的run
方法。然后可以分配并启动子类的一个实例。例如,计算大于规定值的素数的线程可以写成如下形式:
class PrimeThread extends Thread {long minPrime;PrimeThread(long minPrime) {this.minPrime = minPrime;}public void run() {// compute primes larger than minPrime. . .}
}
下面的代码将创建一个线程并开始运行:
PrimeThread p = new PrimeThread(143);
p.start();
创建线程的另一种方法是声明一个实现Runnable
接口的类。然后,该类实现“运行”方法。然后可以分配该类的一个实例,在创建 Thread
时作为参数传递,并启动。另一种样式中的相同示例如下所示:
class PrimeRun implements Runnable {long minPrime;PrimeRun(long minPrime) {this.minPrime = minPrime;}public void run() {// compute primes larger than minPrime. . .}
}
下面的代码将创建一个线程并开始运行:
PrimeRun p = new PrimeRun(143);new Thread(p).start();
出于识别目的,每个线程都有一个名称。多个线程可以具有相同的名称。如果在创建线程时没有指定名称,则会为其生成一个新名称。
除非另有说明,否则将“null”参数传递给此类中的构造函数或方法将导致引发NullPointRexception
。
构造器
构造器 | 说明 |
---|---|
Thread()
|
分配一个新的Thread 对象。
|
Thread(Runnable target)
|
分配一个新的Thread 对象。
|
Thread(Runnable target, String name)
|
分配一个新的Thread 对象。
|
Thread(String name)
|
分配一个新的Thread 对象。
|
Thread(ThreadGroup group, Runnable target)
|
分配一个新的Thread 对象。
|
Thread(ThreadGroup group, Runnable target, String name)
|
分配一个新的Thread 对象,使其以 target 作为其运行对象,以指定的name 作为其名称,并属于group 所引用的线程组。
|
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
|
分配一个新的Thread 对象,使其以target 作为其运行对象,以指定的name 作为其名称,并属于 group 所指的线程组,并具有指定的堆栈大小。
|
Thread(ThreadGroup group, Runnable target, String name, long stackSize, boolean inheritThreadLocals)
|
分配一个新的Thread 对象,使其以“目标”作为其运行对象,以指定的name 作为其名称,属于 group 引用的线程组,以指定的stackSize ,并继承inheritable thread-local变量的初始值,如果inheritThreadLocals 为true 。
|
Thread(ThreadGroup group, String name)
|
分配一个新的Thread 对象。
|
Field
修饰符和类型 | 成员变量 | 描述 |
---|---|---|
static int
|
MAX_PRIORITY
|
线程可以拥有的最大优先级 |
static int
|
MIN_PRIORITY
|
线程可以拥有的最低优先级 |
static int
|
NORM_PRIORITY
|
分配给线程的默认优先级 |
方法
修饰符和类型 | 方法 | 描述 |
---|---|---|
static int
|
activeCount()
|
返回当前线程组及其子组中活动线程数量的估计值 |
void
|
checkAccess()
|
确定当前运行的线程是否有权修改此线程 |
protected Object
|
clone()
|
由于线程不能被有意义地克隆,因此引发CloneNotSupportedException (克隆支持异常) |
static Thread
|
currentThread()
|
返回对当前正在执行的线程对象的引用。 |
static void
|
dumpStack()
|
将当前线程的栈跟踪打印到标准错误流(standard error stream) |
static int
|
enumerate(Thread[] tarray)
|
将当前线程的线程组(thread group)及其子组(subgroups)中的每个活动线程复制到指定数组中 |
static Map<Thread,StackTraceElement[]>
|
getAllStackTraces()
|
Returns a map of stack traces for all live threads |
ClassLoader
|
getContextClassLoader()
|
返回此线程的上下文ClassLoader
|
static Thread.UncaughtExceptionHandler
|
getDefaultUncaughtExceptionHandler()
|
返回线程因未捕获的异常而突然终止时调用的默认处理程序 |
long
|
getId()
|
返回此线程的标识符 |
String
|
getName()
|
返回该线程的名称 |
int
|
getPriority()
|
返回该线程的优先级 |
StackTraceElement[]
|
getStackTrace()
|
返回表示此线程堆栈转储的堆栈跟踪元素数组 |
Thread.State
|
getState()
|
返回此线程的状态 |
ThreadGroup
|
getThreadGroup()
|
返回该线程所属的线程组 |
Thread.UncaughtExceptionHandler
|
getUncaughtExceptionHandler()
|
返回当此线程由于未捕获的异常而突然终止时调用的处理程序 |
static boolean
|
holdsLock(Object obj)
|
当且仅当当前线程持有指定对象的监视器锁时,返回 true
|
void
|
interrupt()
|
中断这个线程 |
static boolean
|
interrupted()
|
测试当前线程是否已被中断 |
boolean
|
isAlive()
|
测试该线程是否是活动的 |
boolean
|
isDaemon()
|
测试该线程是否是守护线程 |
boolean
|
isInterrupted()
|
测试该线程是否已被中断 |
void
|
join()
|
Waits for this thread to die |
void
|
join(long millis)
|
等待此线程死亡的时间最多为“毫秒(milliseconds )” |
void
|
join(long millis, int nanos)
|
等待此线程死亡的时间最多为“毫秒millis”加上“毫微秒nanos” |
static void
|
onSpinWait()
|
表示呼叫者暂时无法继续进行,直到其他活动发生一个或多个动作 |
void
|
run()
|
If this thread was constructed using a separate Runnable run object, then that Runnable object’s run method is called; otherwise, this method does nothing and returns
|
void
|
setContextClassLoader(ClassLoader cl)
|
Sets the context ClassLoader for this Thread |
void
|
setDaemon(boolean on)
|
Marks this thread as either a daemon thread or a user thread |
static void
|
setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
|
设置当线程由于未捕获的异常而突然终止时调用的默认处理程序,并且没有为该线程定义其他处理程序 |
void
|
setName(String name)
|
将此线程的名称更改为等于参数name
|
void
|
setPriority(int newPriority)
|
更改此线程的优先级 |
void
|
setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
|
设置当此线程由于未捕获的异常而突然终止时调用的处理程序 |
static void
|
sleep(long millis)
|
根据系统计时器和调度程序的精度和准确度,使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数 |
static void
|
sleep(long millis, int nanos)
|
使当前正在执行的线程休眠(暂时停止执行)指定的毫秒数加上指定的纳秒数,这取决于系统计时器和调度程序的精度和准确度 |
void
|
start()
|
导致此线程开始执行;Java虚拟机调用这个线程的run 方法
|
String
|
toString()
|
返回此线程的字符串表示形式,包括线程的名称、优先级和线程组 |
static void
|
yield()
|
给调度程序的提示,当前线程愿意让出它当前对处理器的使用 |
当前仍在编辑文章 - Java 并 发 编 程 基 础相关推荐
- 当前仍在编辑文章 - Java Excel处理 - 实操案例与方法手册
Java Excel处理 - 草稿 使用python做数据分析的人知道,在python中,读取Excel比较方便.最简单的莫过于pandas的read_excel()方法了,而保存Excel也只需要p ...
- 部分仍在编辑文章 - Python基础专题 - 深度解析python中的赋值与拷贝
深度解析python中的赋值与拷贝 jcLee95 的 CSDN 博客:https://blog.csdn.net/qq_28550263?spm=1011.2124.3001.5343 邮箱 :29 ...
- dede/archives_do.php,dedecms后台编辑文章时archives_do.php显示空白解决办法
今天网站后台不知道哪里搞错了,后台总是出现状况,出现无法dede后台编辑文章显示空白的问题,查看编辑文章的文件是archives_do.php 这个文件. 然后找到文件了就可以查看出现的问题了,我们发 ...
- java测试驱动开发(TDD)之《井字游戏》
为什么80%的码农都做不了架构师?>>> 永久更新地址:https://my.oschina.net/bysu/blog/1632393 写在前面:若有侵权,请发邮件by.su ...
- SpringBoot+Vue+Mybatis-plus 博客(四):完成发布文章、编辑文章、删除文章及查询文章功能
SpringBoot+Vue+Mybatis-plus 博客:个人博客介绍及效果展示 SpringBoot+Vue+Mybatis-plus 博客(一):完成博客后台前端登录页面.后端登录接口 Spr ...
- 关于博客园,编辑文章的小意见
来博客园两天了,给我的感觉挺不错的,后台功能也很强大的.我很喜欢.但我发现在使用过程中有个不太方便的地方.就是写好一篇文章后,我发现没有这篇文章分类时,我把文章和标题复制出来,去"编辑个人分 ...
- 推荐您使用 Markdown 来编辑文章
什么是Markdown? Markdown : 是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. 简单地说就是通过一些符号使你的文章排版更加清晰.简 ...
- php文章发布时间修改,Dedecms编辑文章更新当前时间的修改方法
关于Dedecms的发布时间问题,前些有位站长咨询烈火小编,正好最近dede58又上线了Dedecms的源码下载频道,在编辑和审核软件时,经常要把以前的时间更新到现在的时间,手动输入真的太麻烦了,加上 ...
- Java Email 发HTML邮件工具 采用 freemarker模板引擎渲染
Java Email 发HTML邮件工具 采用 freemarker模板引擎 1.常用方式对比 Java发送邮件有很多的实现方式 第一种:Java 原生发邮件mail.jar和activation.j ...
最新文章
- CSS 和 JS 动画哪个更快
- mysql数据库中的十进位是什么意思?
- MySql数据库查询结果用表格输出PHP代码示例
- 编写可变参数函数 c语言,C语言中编写可变参数函数
- 关于业务架构的一些思考与实践
- [python pycharm pytorch debug sets]
- software engineering homework, product analysis
- python minimize_Python数学规划案例一
- 猫都能学会的Unity3D Shader入门指南(二)
- linux整行剪切_云计算人员如何提高效率 要掌握哪些Linux命令
- hadoop 集群调度 Azkaban2搭建
- 牛客网 牛客练习赛7 A.骰子的游戏
- 使用Cloudflare API动态解析域名IP
- Oracle安装之后电脑变慢
- Java 8 日期和时间
- Foo,getName题解分析
- 【打卡-Coggle竞赛学习2023年3月】对话意图识别
- C语言volatile修饰的到底什么鬼?原来它在嵌入式开发是必须掌握的!
- 使用Keras进行深度学习:(六)LSTM和双向LSTM讲解及实践
- 关于线性稳压器的五个设计细节