CoreJava 笔记总结-第十二章 并发-1

第十二章 并发

线程

package chapter12_concurrent.threads;public class ThreadsTest {public static final int DELAY = 10;public static final int STEPS = 100;public static final double MAX_AMOUNT = 1000;public static void main(String[] args) {var bank = new Bank(4, 100000);//Runnalbe 是一个函数式接口,可以用一个lambda表达式创建一个实例Runnable task1 = () -> {try {for (int i = 0; i < STEPS; i++) {double amount = MAX_AMOUNT * Math.random();bank.transfer(0, 1, amount);Thread.sleep((long) (DELAY * Math.random()));}} catch (InterruptedException e) {}};Runnable task2 = () -> {try {for (int i = 0; i < STEPS; i++) {double amount = MAX_AMOUNT * Math.random();bank.transfer(2, 3, amount);//休眠制定的毫秒数Thread.sleep((long) ( DELAY * Math.random()));}} catch (InterruptedException e) {}};//构造一个Thread对象,启动线程new Thread(task1).start();new Thread(task2).start();}
}

线程状态

  • New, Runnable, Blocked, Waiting, Timed waiting, Terminated

分别表示线程的六种状态: 新建, 可运行, 阻塞, 等待, 计时等待, 终止


新建线程

  • new Thread(r) 新建线程, 但是还没有开始运行

可运行线程

  • 调用start方法后线程就属于可运行状态, 处于runnable可能运行也可能没有运行

阻塞和等待进程

  • 线程处于阻塞和等待状态不活动,不运行任何代码,消耗最少资源
  • 当线程试图获取一个内部的对象锁,而该锁目前被其他线程占有,该线程就会被阻塞.所有其他线程释放这个锁,并且线程调度器允许该线程持有这个锁,他将变成非阻塞状态
  • 当线程等待另一个线程通知调度器出现一个条件时,这个线程会进入等待状态
  • 有的方法有超时参数,调用这些方法会让线程进入计时等待状态.这一状态会一直等待到超时期满或者接收到适当的通知

终止线程

  • run方法正常退出
  • 一个没有捕获的异常终止了run方法

线程属性

中断线程

  • interrupt方法可以用来请求终止一个线程,程序调用该方法就会设置线程中断状态
  • 测试是否设置了中断状态:Thread.currentThread()获得当前线程
while(!Thread.currentThread().isInterrupted()){...   
}
  • 线程被阻塞就无法检查中断状态

  • 当在一个被sleep, wait调用的阻塞的线程上调用interrupt方法,那个阻塞调用将被一个InterruptedException异常中断

  • 一般将中断解释为一个中止请求

  • 如果循环调用了sleep,不要检测中断状态,应当捕获InterruptedException

  • interrupted: 静态方法, 检查当前线程是否中断,并且清楚线程中断状态

  • isInterrupted: 实例方法, 检查是否有线程被中断,不改变中断状态

  • 不要抑制InterruptedException异常:

    • catch子句中调用Thread.currentThread().interrupt()设置中断状态,调用者就可以检查中断状态了

    • void mySubTask(){...try{sleep(delay);}catch(InterruptedException e){Thread.currentThread().interrupt()}
      }
      
    • 更好的是,标记方法,去掉try语句块

    • void mySubTask() throw InterruptedException
      {    ...   sleep(delay);    
      }    
      

守护线程

  • t.setDaemon(true);
  • 守护线程唯一作用就是为其他线程提供服务

线程名

  • 默认状态下有容易记忆的名字
  • 改名:setName(...)

未捕获异常的处理器

  • 线程组ThreadGroup类实现了Thread.UncaughtExceptionHandler接口,其uncaughtException方法执行以下操作:
    1. 该线程若有父线程那么调用父线程的uncaughtException方法
    2. 如果Thread.getDefaultExceptionHandler方法返回一个非null处理器,调用该处理器
    3. 否则,如果Throwable类是ThreadDeath的一个实例,什么也不做
    4. 否则将线程的名字和Throwable栈轨迹输出到System.err

线程的优先级

  • setPriority方法提高或者降低任何一个线程的优先级
  • MIN_PRIORITY(1), NORM_PRIORITY(5), MAX_PRIORITY(10)

同步

  • 竞态条件: 两个及以上线程共享对同一组数据的存取, 线程相互覆盖导致对象破坏
  • 不同步的操作:
package chapter12_concurrent.unsynch;public class UnsynchBankTest {public static final int NACCOUNT = 100;public static final double INITIAL_BALANCE = 1000;public static final double MAX_AMOUNT = 1000;public static final int DELAY = 10;public static void main(String[] args) {var bank = new Bank(NACCOUNT, INITIAL_BALANCE);for (int i = 0; i < NACCOUNT; i++) {int fromAccount = i;Runnable r = () -> {try {while (true) {int toAccount = (int) (bank.size() * Math.random());double amount = MAX_AMOUNT * Math.random();bank.transfer(fromAccount, toAccount, amount);Thread.sleep((int) (DELAY * Math.random()));}} catch (InterruptedException e) {}};var t = new Thread(r);t.start();}}
}

锁对象

  • 两种机制可以防止并发访问代码块: synchronized, ReentrantLock
  • 基本结构:
mylock.lock();
try{critical section
}
finally{myLock.unlock();
}
  • 该结构确保任何时刻只有一个线程进入临界区,一旦一个线程锁定了锁对象,其他任何线程无法通过lock语句
  • 要把unlock放入finally语句.如果临界区代码异常,锁必须释放,否则线程永远阻塞
public class bank{private ReentrantLock bankLock = new ReentrantLock();......public void transfer(int from, int to, double amount){bankLock.lock();try {if (accounts[from] < amount) return;System.out.print(Thread.currentThread());accounts[from] -= amount;System.out.printf(" %10.2f from %d to %d", amount, from, to);accounts[to] += amount;System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());}finally {bankLock.unlock();}}
}
  • 每个bank有自己的ReentrantLock对象,两个线程视图访问同一个bank对象,锁可以用来保证串行化访问
  • 两个线程访问不同的bank对象,每个线程会得到不同的锁对象,线程不会阻塞

条件对象

  • 下面的Bank类加入了锁对象, 保护金额转账不够时候线程覆盖的情况
  • 引入了条件对象, 调用await方法将当前线程暂停,放弃锁,允许其他线程执行
  • 另一个线程完成转账后调用signalAll重新激活等待这个条件的所有线程
  • 其中的某个线程将从await调用处返回得到这个锁,继续执行之前暂停的地方
package chapter12_concurrent.synch;import java.util.*;
import java.util.concurrent.locks.*;public class Bank {private final double[] accounts;private ReentrantLock banklock;private Condition sufficientFunds;public Bank(int n, double initialBalance) {accounts = new double[n];Arrays.fill(accounts, initialBalance);banklock = new ReentrantLock();sufficientFunds = banklock.newCondition();}public void transfer(int from, int to, double amount) throws InterruptedException{banklock.lock();try {while (accounts[from] < amount) {sufficientFunds.await();}System.out.println(Thread.currentThread());accounts[from] -= amount;System.out.printf(" %10.2f from %d to %d.", amount, from, to);accounts[to] += amount;System.out.printf(" Total balance: %10.2f%n", getTotalBanlance());sufficientFunds.signalAll();}finally {banklock.unlock();}}public double getTotalBanlance() {banklock.lock();try {double sum = 0.0;for (double a: accounts)sum += a;return sum;}finally {banklock.unlock();}}public int size() {return accounts.length;}
}

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

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

相关文章

走迷宫-双向bfs解法

双向bfs适用于知道起点和终点的状态下使用&#xff0c;从起点和终点两个方向开始进行搜索&#xff0c;可以非常大的提高单个bfs的搜索效率同样&#xff0c;实现也是通过队列的方式&#xff0c;可以设置两个队列&#xff0c;一个队列保存从起点开始搜索的状态&#xff0c;另一个…

.NET Core开发实战(第16课:选项数据热更新:让服务感知配置的变化)--学习笔记...

16 | 选项数据热更新&#xff1a;让服务感知配置的变化选项框架还有两个关键类型&#xff1a;1、IOptionsMonitor2、IOptionsSnapshot场景&#xff1a;1、范围作用域类型使用 IOptinsSnapshot2、单例服务使用 IOptionsMonitor通过代码更新选项&#xff1a;IPostConfigureOption…

CoreJava 笔记总结-第十二章 并发-2

文章目录第十二章 并发synchronized关键字同步块监视器概念volatile字段final变量原子性死锁线程安全的集合阻塞队列映射条目的原子更新对并发散列映射的批操作并行数组算法同步包装器任务和线程池Callable, FutureExecutor执行器fork-in框架异步计算可完成Future组合可完成Fut…

八数码问题II-bfs和map标记

问题描述&#xff1a; 在33的棋盘上&#xff0c;摆有八个棋子&#xff0c;每个棋子上标有1至8的某一数字。棋盘中留有一个空格&#xff0c;空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是&#xff1a; 给出一种初始布局&#xff08;初始状态&#xff09;和目标布…

华为任职资格_看了华为的任职资格体系,你就明白员工为啥这么拼?

提到华为的18万奋斗者&#xff0c;职场上没人不竖起大拇指。而优秀人才的背后&#xff0c;就像任正非曾说过的那样&#xff0c;华为的成功&#xff0c;很大意义上讲就是人力资源的成功。华为的人力资源管理最有代表性的&#xff0c;除了狼性文化和薪酬绩效外&#xff0c;就是任…

如何使用有序GUID提升数据库读写性能

源宝导读&#xff1a;数据库设计时&#xff0c;经常会使用GUID作为表的主键&#xff0c;但由于GUID的随机性会导致数据库在读写数据时效率严重下降&#xff0c;影响应用程序整体性能。本文将深入探讨如何通过使用有序GUID提升数据读写的性能。一、背景常见的数据库设计是使用连…

八数码问题II-双向bfs和map标记

问题描述&#xff1a; 在33的棋盘上&#xff0c;摆有八个棋子&#xff0c;每个棋子上标有1至8的某一数字。棋盘中留有一个空格&#xff0c;空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是&#xff1a; 给出一种初始布局&#xff08;初始状态&#xff09;和目标布…

MarkDown语法, 快捷键,Dos命令

文章目录MarkDown 语法计算机软件快捷键Dos命令MarkDown 语法 字体: 斜体, 粗体, 删除图片: ![title](link)超链接: [words](link)引用>标题列表表格 名字|性别|生日 31辅导班VS看复旦南开都是vs1ds代码块 分割线*** 计算机软件 系统软件应用软件DOS, Windows, Unix,…

《商业洞察力30讲》学习笔记(上)

【洞察力】| 作者 / Edison Zhou这是恰童鞋骚年的第197篇原创文章学习洞察力&#xff0c;也是新时代IT人员的一门进阶必修课...1学习背景2019年下半年至今&#xff0c;在领导的推荐下学习了刘润老师的《商业洞察力30讲》&#xff0c;刷新了我对于事物的认知&#xff0c;也为我提…

[蓝桥杯][历届试题]九宫重排-双向bfs和map标记

题目描述 如下面第一个图的九宫格中&#xff0c;放着 1~8 的数字卡片&#xff0c;还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动&#xff0c;可以形成第二个图所示的局面。 我们把第一个图的局面记为&#xff1a;12345678. 把第二个图的局面记…

3月数据库排行:前10整体下行,出新技术了?

DB-Engines 数据库流行度排行榜 3 月更新已发布&#xff0c;排名前二十如下&#xff1a;排名方面没有任何变动&#xff08;仅针对前十&#xff09;&#xff0c;相信很长一段时间内也都不会变动&#xff0c;毕竟巨头的位置不是一时半刻就能动摇的。不过这个月的排行榜还是有值得…

CSS3动画大全(附源码)flex布局,grid布局3d旋转,图像模糊,文字发光

CSS3动画大全(附源码)3d旋转,图像模糊,文字发光! 文章目录CSS3动画大全(附源码)3d旋转,图像模糊,文字发光!html代码cssgrid布局flex布局文字发光 & 图像放缩3d旋转 图像移动源码html代码 <body><div class"container"><div class"main"…

每日一题——LeetCode160.相交链表

个人主页&#xff1a;白日依山璟 专栏&#xff1a;Java|数据结构与算法|每日一题 文章目录 1. 题目描述示例1&#xff1a;示例2&#xff1a;提示&#xff1a; 2. 思路3. 代码 1. 题目描述 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的…

[蓝桥杯][2013年第四届真题]买不到的数目-模拟,数论

题目描述 小明开了一家糖果店。他别出心裁&#xff1a;把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。 小朋友来买糖的时候&#xff0c;他就用这两种包装来组合。当然有些糖果数目是无法组合出来的&#xff0c;比如要买 10 颗糖。 你可以用计算机测试一下&#xff0c;在…

.NET Core的HttpClient连接池管理

译者荐语&#xff1a;使用.NET Core的HttpClient连接池管理有哪些注意事项&#xff1f;本文给出了非常中肯的建议。原文来自互联网&#xff0c;由长沙DotNET技术社区编译。如译文侵犯您的署名权或版权&#xff0c;请联系小编&#xff0c;小编将在24小时内删除。本文来源[1]史蒂…

[蓝桥杯][2014年第五届真题]兰顿蚂蚁-模拟

题目描述 兰顿蚂蚁&#xff0c;是于1986年&#xff0c;由克里斯兰顿提出来的&#xff0c;属于细胞自动机的一种。 平面上的正方形格子被填上黑色或白色。在其中一格正方形内有一只“蚂蚁”。 蚂蚁的头部朝向为&#xff1a;上下左右其中一方。 蚂蚁的移动规则十分简单&#…

.NET Core开发实战(第17课:为选项数据添加验证:避免错误配置的应用接收用户流量)--学习笔记...

17 | 为选项数据添加验证&#xff1a;避免错误配置的应用接收用户流量三种验证方法1、直接注册验证函数2、实现 IValidateOptions3、使用 Microsoft.Extensions.Options.DataAnnotations延用上一节代码需要添加验证的时候不能用 Configure&#xff0c;而用 AddOptions 方法//se…

[蓝桥杯][2014年第五届真题]分糖果-模拟

题目描述 问题描述 有n个小朋友围坐成一圈。老师给每个小朋友随机发偶数个糖果&#xff0c;然后进行下面的游戏&#xff1a; 每个小朋友都把自己的糖果分一半给左手边的孩子。 一轮分糖后&#xff0c;拥有奇数颗糖的孩子由老师补给1个糖果&#xff0c;从而变成偶数。 反复进…

分支程序与循环程序设计-汇编实验二

DATA SEGMENT ;定义数据段BUF DB -1, 20, 3, 30, -5, 15, 100, -54, 0, 4, 78, 99DB -12, 32, 3, 23, -7, 24, 60,-51 ;定义比较大小的数据DATA ENDS ;数据段结束ESEG SEGMENT ;定义附加段RES1 DB 0;定义结果存放区RES2 DB 0RES3 DB 0 ESEG ENDS ;附加段结束CODE SEGMENT ;定义…

[蓝桥杯][2013年第四届真题]剪格子-dfs

题目描述 历届试题 剪格子 时间限制&#xff1a;1.0s 内存限制&#xff1a;256.0MB 问题描述 如下图所示&#xff0c;3 x 3 的格子中填写了一些整数。 我们沿着图中的星号线剪开&#xff0c;得到两个部分&#xff0c;每个部分的数字和都是60。 本题的要求就是请你编程判定&a…