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虚拟机继续执行线程,直到出现以下任一情况:

  • Runtimeexit方法已被调用,安全管理器已允许退出操作发生。
  • 所有不是守护线程的线程都已经死亡,要么是从调用run方法返回,要么是抛出一个传播到“运行”方法之外的异常。

有两种方法可以创建新的执行线程。一种是将一个类声明为 Thread的子类。这个子类应该覆盖类 Threadrun方法。然后可以分配并启动子类的一个实例。例如,计算大于规定值的素数的线程可以写成如下形式:


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变量的初始值,如果inheritThreadLocalstrue
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 并 发 编 程 基 础相关推荐

  1. 当前仍在编辑文章 - Java Excel处理 - 实操案例与方法手册

    Java Excel处理 - 草稿 使用python做数据分析的人知道,在python中,读取Excel比较方便.最简单的莫过于pandas的read_excel()方法了,而保存Excel也只需要p ...

  2. 部分仍在编辑文章 - Python基础专题 - 深度解析python中的赋值与拷贝

    深度解析python中的赋值与拷贝 jcLee95 的 CSDN 博客:https://blog.csdn.net/qq_28550263?spm=1011.2124.3001.5343 邮箱 :29 ...

  3. dede/archives_do.php,dedecms后台编辑文章时archives_do.php显示空白解决办法

    今天网站后台不知道哪里搞错了,后台总是出现状况,出现无法dede后台编辑文章显示空白的问题,查看编辑文章的文件是archives_do.php 这个文件. 然后找到文件了就可以查看出现的问题了,我们发 ...

  4. java测试驱动开发(TDD)之《井字游戏》

    为什么80%的码农都做不了架构师?>>>    永久更新地址:https://my.oschina.net/bysu/blog/1632393 写在前面:若有侵权,请发邮件by.su ...

  5. SpringBoot+Vue+Mybatis-plus 博客(四):完成发布文章、编辑文章、删除文章及查询文章功能

    SpringBoot+Vue+Mybatis-plus 博客:个人博客介绍及效果展示 SpringBoot+Vue+Mybatis-plus 博客(一):完成博客后台前端登录页面.后端登录接口 Spr ...

  6. 关于博客园,编辑文章的小意见

    来博客园两天了,给我的感觉挺不错的,后台功能也很强大的.我很喜欢.但我发现在使用过程中有个不太方便的地方.就是写好一篇文章后,我发现没有这篇文章分类时,我把文章和标题复制出来,去"编辑个人分 ...

  7. 推荐您使用 Markdown 来编辑文章

    什么是Markdown? Markdown : 是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. 简单地说就是通过一些符号使你的文章排版更加清晰.简 ...

  8. php文章发布时间修改,Dedecms编辑文章更新当前时间的修改方法

    关于Dedecms的发布时间问题,前些有位站长咨询烈火小编,正好最近dede58又上线了Dedecms的源码下载频道,在编辑和审核软件时,经常要把以前的时间更新到现在的时间,手动输入真的太麻烦了,加上 ...

  9. Java Email 发HTML邮件工具 采用 freemarker模板引擎渲染

    Java Email 发HTML邮件工具 采用 freemarker模板引擎 1.常用方式对比 Java发送邮件有很多的实现方式 第一种:Java 原生发邮件mail.jar和activation.j ...

最新文章

  1. CSS 和 JS 动画哪个更快
  2. mysql数据库中的十进位是什么意思?
  3. MySql数据库查询结果用表格输出PHP代码示例
  4. 编写可变参数函数 c语言,C语言中编写可变参数函数
  5. 关于业务架构的一些思考与实践
  6. [python pycharm pytorch debug sets]
  7. software engineering homework, product analysis
  8. python minimize_Python数学规划案例一
  9. 猫都能学会的Unity3D Shader入门指南(二)
  10. linux整行剪切_云计算人员如何提高效率 要掌握哪些Linux命令
  11. hadoop 集群调度 Azkaban2搭建
  12. 牛客网 牛客练习赛7 A.骰子的游戏
  13. 使用Cloudflare API动态解析域名IP
  14. Oracle安装之后电脑变慢
  15. Java 8 日期和时间
  16. Foo,getName题解分析
  17. 【打卡-Coggle竞赛学习2023年3月】对话意图识别
  18. C语言volatile修饰的到底什么鬼?原来它在嵌入式开发是必须掌握的!
  19. 使用Keras进行深度学习:(六)LSTM和双向LSTM讲解及实践
  20. 关于线性稳压器的五个设计细节

热门文章

  1. LeetCode 138. Copy List with Random Pointer
  2. 【递归】剑指offer——面试题19:二叉树的镜像
  3. 【机器学习】一些模型的位置总结
  4. 一道非齐次方程组解的判定习题--行向量
  5. Leetcode 58 之反向迭代器的使用
  6. Linux下Qt使用QAudio相关类进行音频采集,使用Windows下的Matlab软件播放
  7. 如何设计学术海报(翻译)
  8. Leetcode-5063 Last Stone Weight(最后一块石头的重量)
  9. Java的clone方法
  10. get传输时,会将加号+ 转换为空格