深入浅出Java多线程--慕课网笔记
来源:互联网 发布:路由器怎么映射端口 编辑:程序博客网 时间:2024/06/10 00:49
1-2java多线程基础概念介绍
- 进程:程序(任务)的执行过程持有资源(共享内存,共享文件)和线程
线程:qq聊天、收发文件
*线程是系统中最小的执行单元
同一进程中有多个线程
线程共享进程的资源**线程的交互
互斥 同步*
java中线程的常用方法介绍:
java对线程的支持线程的创建和启动线程常用方法如何停止线程
java.lang
*class Thread
interface Runnable*
run()
Thread常用方法
- 线程的创建
Thread()
Thread(String name)
Thread(Runnable target)
Thread(Runnable target,String name) - 线程的方法
启动线程:
start()
线程休眠:
sleep(long millis)
sleep(long millis,intnanos)
使其他线程等待当前线程终止:
join()
join(long millis)
join(long millis,int nanos)
当前运行线程释放处理器资源:
yield() - 获取线程引用
返回当前运行的线程引用:
currentThread()
2-2java线程-隋唐演义框架说明
//军队线程//模拟作战双方的行为public class ArmRunnable implements Runnable{}
ArmRunnable armyTaskOfSuiDynasty = new ArmyRunnable();ArmRunnable armyTaskOfarmyOfRevolt = new ArmyRunnable();
//使用Runnable接口创建线程Thread armyOfSuiDynasty = new Thread(armyTaskOfSuiDynasty,"随军");Thread armyOfRevolt = new Thread(armyTaskOfarmyOfRevolt,"农民起义军");
public class KeyPersonThread extends Thread{ public KeyPersonThread(String name){ super(name); } @Override public void run(){ System.out.println(Thread.currentThread().getName()+"开始了战斗"); for(int i=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+"左突右杀,攻击随军。。。"); } System.out.println(Thread.currentThread().getName()+"结束战斗!"); } }
/** * 隋唐演义大戏舞台 */public class Stage extends Thread{}
综上所述:
*军队:ArmyRunnble
英雄人物:KeyPersonThread
舞台:Stage*
2-3Java线程-隋唐演义实战开发–演员简介
演员
*Mr.Thread
Ms.Runnable*
public class Actor extends Thread { public void run(){ System.out.println(getName()+"是一个演员!"); int count = 0; boolean keepRunning = true; while(keepRunning){ System.out.println(getName()+"登台演出:"+ (++count)); if(count == 100){ keepRunning = false; } if(count%10== 0){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println(getName()+"的演出结束了!"); } public static void main(String[] args){ Thread actor = new Actor(); actor.setName("Mr. Thread"); actor.start(); Thread actressThread = new Thread(new Actress(),"Ms. Runnable"); actressThread.start(); }}class Actress implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"是一个演员!"); int count = 0; boolean keepRunning = true; while(keepRunning){ System.out.println(Thread.currentThread().getName()+"登台演出:"+ (++count)); if(count == 100){ keepRunning = false; } if(count%10== 0){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println(Thread.currentThread().getName()+"的演出结束了!"); }}
2-4Java线程-隋唐演义实战开发–军队线程
2-5Java线程-隋唐演义实战开发–关键先生
//军队线程//模拟作战双方的行为public class ArmyRunnable implements Runnable { //volatile保证了线程可以正确的读取其他线程写入的值 //可见性 ref JMM, happens-before原则 volatile boolean keepRunning = true; @Override public void run() { while(keepRunning){ //发动5连击 for(int i=0;i<5;i++){ System.out.println(Thread.currentThread().getName()+"进攻对方["+i+"]"); //让出了处理器时间,下次该谁进攻还不一定呢! Thread.yield(); } } System.out.println(Thread.currentThread().getName()+"结束了战斗!"); }}
public class KeyPersonThread extends Thread { public void run(){ System.out.println(Thread.currentThread().getName()+"开始了战斗!"); for(int i=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+"左突右杀,攻击隋军..."); } System.out.println(Thread.currentThread().getName()+"结束了战斗!"); }}
/** * 隋唐演义大戏舞台 */public class Stage extends Thread { public void run(){ System.out.println("欢迎观看隋唐演义"); //让观众们安静片刻,等待大戏上演 try { Thread.sleep(5000); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("大幕徐徐拉开"); try { Thread.sleep(5000); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println("话说隋朝末年,隋军与农民起义军杀得昏天黑地..."); ArmyRunnable armyTaskOfSuiDynasty = new ArmyRunnable(); ArmyRunnable armyTaskOfRevolt = new ArmyRunnable(); //使用Runnable接口创建线程 Thread armyOfSuiDynasty = new Thread(armyTaskOfSuiDynasty,"隋军"); Thread armyOfRevolt = new Thread(armyTaskOfRevolt,"农民起义军"); //启动线程,让军队开始作战 armyOfSuiDynasty.start(); armyOfRevolt.start(); //舞台线程休眠,大家专心观看军队厮杀 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("正当双方激战正酣,半路杀出了个程咬金"); Thread mrCheng = new KeyPersonThread(); mrCheng.setName("程咬金"); System.out.println("程咬金的理想就是结束战争,使百姓安居乐业!"); //停止军队作战 //停止线程的方法 armyTaskOfSuiDynasty.keepRunning = false; armyTaskOfRevolt.keepRunning = false; try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } /* * 历史大戏留给关键人物 */ mrCheng.start(); //万众瞩目,所有线程等待程先生完成历史使命 try { mrCheng.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("战争结束,人民安居乐业,程先生实现了积极的人生梦想,为人民作出了贡献!"); System.out.println("谢谢观看隋唐演义,再见!"); } public static void main(String[] args) { new Stage().start(); }}
3-1Java线程停止的错误方法–stop
not stop()方法
戛然而止完成了什么那些工作还没有做清理工作
3-2Java线程停止正确的方法–设置退出标志
volatile boolean keepRunning = true;
3-3Java线程停止广为流传的错误方法–interrupt方法
interrupt方法初衷并不是停止线程
4-1Java线程交互之汽车人之忧:消失的能量
4-2Java线程交互之能量损失之谜:争用条件
Race Condition
*当多个线程同时共享访问同一数据(内存区域)时,每个线程都尝
试操作该数据,从而导致数据破坏(corrupted),这种现象称为争
用条件*。
4-3Java线程交互之互斥与同步:守恒的能量
/** * 宇宙的能量系统 * 遵循能量守恒定律: * 能量不会凭空创生或消失,只会从一处转移到另一处 */public class EnergySystem { //能量盒子,能量存贮的地方 private final double[] energyBoxes; private final Object lockObj = new Object(); /** * * @param n 能量盒子的数量 * @param initialEnergy 每个能量盒子初始含有的能量值 */ public EnergySystem(int n, double initialEnergy){ energyBoxes = new double[n]; for (int i = 0; i < energyBoxes.length; i++) energyBoxes[i] = initialEnergy; } /** * 能量的转移,从一个盒子到另一个盒子 * @param from 能量源 * @param to 能量终点 * @param amount 能量值 */ public void transfer(int from, int to, double amount){ synchronized(lockObj){// if (energyBoxes[from] < amount)// return; //while循环,保证条件不满足时任务都会被条件阻挡 //而不是继续竞争CPU资源 while (energyBoxes[from] < amount){ try { //条件不满足, 将当前线程放入Wait Set lockObj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.print(Thread.currentThread().getName()); energyBoxes[from] -= amount; System.out.printf("从%d转移%10.2f单位能量到%d", from, amount, to); energyBoxes[to] += amount; System.out.printf(" 能量总和:%10.2f%n", getTotalEnergies()); //唤醒所有在lockObj对象上等待的线程 lockObj.notifyAll(); } } /** * 获取能量世界的能量总和 */ public double getTotalEnergies(){ double sum = 0; for (double amount : energyBoxes) sum += amount; return sum; } /** * 返回能量盒子的长度 */ public int getBoxAmount(){ return energyBoxes.length; }}
public class EnergySystemTest { //将要构建的能量世界中能量盒子数量 public static final int BOX_AMOUNT = 100; //每个盒子初始能量 public static final double INITIAL_ENERGY = 1000; public static void main(String[] args){ EnergySystem eng = new EnergySystem(BOX_AMOUNT, INITIAL_ENERGY); for (int i = 0; i < BOX_AMOUNT; i++){ EnergyTransferTask task = new EnergyTransferTask(eng, i, INITIAL_ENERGY); Thread t = new Thread(task,"TransferThread_"+i); t.start(); } }}
public class EnergyTransferTask implements Runnable{ //共享的能量世界 private EnergySystem energySystem; //能量转移的源能量盒子下标 private int fromBox; //单次能量转移最大单元 private double maxAmount; //最大休眠时间(毫秒) private int DELAY = 10; public EnergyTransferTask(EnergySystem energySystem, int from, double max){ this.energySystem = energySystem; this.fromBox = from; this.maxAmount = max; } public void run() { try{ while (true){ int toBox = (int) (energySystem.getBoxAmount()* Math.random()); double amount = maxAmount * Math.random(); energySystem.transfer(fromBox, toBox, amount); Thread.sleep((int) (DELAY * Math.random())); } }catch (InterruptedException e){ e.printStackTrace(); } }}
4-4Java线程交互之深入剖析互斥与同步
- 互斥的实现:synchronized(intrinsic lock)
同步的实现:wait()/notify()/notifyAll()
*wait set
critical section *
5-1总结及展望
- 如何创建线程及线程的基本操作
- 可见性及volatile关键字
- 争用条件
- 线程的互斥synchronized
- 线程的同步wait/notifyAll
扩展建议
Java Menory Model
- MM描述了Java线程如何通过内存进行交互
- happens-before
- synchronized,volatile&final*
Locks&Condition
- Java锁机制和等待条件的高级实现
- java.util.concurrent.locks
线程安全性
- 原子性与可见性
- java.util.concurrent.atomic
- synchronized & volatile
- DeadLocks
多线程编程常用的交互模型
- Producer-Consumer模型
- Read-Write Lock模型
- Future模型
- Worker Thread模型
Java5中并发编程工具
- java.util.concurrent
- 线程池ExecutorService
- Callable & Future
- BlockingQueue
书籍推荐
- 《CORE JAVA》
- 《JAVA CONCURRENCY IN PRACTICE》
深入浅出Java多线程视频
阅读全文
0 0
- 深入浅出Java多线程--慕课网笔记
- 慕课网 深入浅出java多线程
- 深入浅出java多线程
- 深入浅出Java多线程程序设计
- 深入浅出Java多线程程序设计
- 深入浅出Java多线程程序设计
- 深入浅出JAVA多线程(一)
- 深入浅出Java多线程程序设计
- Java 多线程深入浅出
- 深入浅出Java多线程编程
- 深入浅出Java多线程程序设计
- 深入浅出java多线程
- Java基础---深入浅出多线程
- 深入浅出Java多线程
- java 多线程深入浅出的分析
- 多线程 《深入浅出 Java Concurrency》目录
- 深入浅出java多线程(总结)
- 深入浅出Java多线程(1)-方法 join
- JAVESE基础(六)
- Oracle PL/SQL开发基础(第二十七弹:事务处理简介)
- 八大排序算法之-选择排序 java代码
- Lintcode98 Sort List solution 题解
- 计蒜客 方程的解数
- 深入浅出Java多线程--慕课网笔记
- 【洛谷P2423】双塔
- angular2-http
- python:numpy 文件存取
- How Many Tables(并查集)
- Java获取客户端IP
- 设计模式之外观模式
- 两个输出文件名解析为同一个输出路径:“obj\x86\Debug\xxxxxxxxxxxxx.resources”
- 什么是java 序列化,如何实现java 序列化?