结构化并发应用程序
1)任务执行:当围绕“任务执行”来设计应用程序结构时,第一步就是要找出清晰的任务边界。在理想情况下,各个任务之间是相互独立的:任务并不依赖于其他任务的状态、结果或边界效应。【如:大多数服务器应用程序:以独立的客户请求为边界。Web服务器、邮件服务器、文件服务器、EJB服务器以及数据库服务器等,均通过网络接受远程客户的连接请求】
2)任务取消原因:用户请求取消、有时间现在的操作、应用程序事件、错误、关闭。
3)取消方式——协作式机制:①设置某个“已请求取消”表中,任务定期查看该标志;②中断,每个线程都有一个boolean类型的中断状态:public void interrupt(){…};public Boolean isInterrupted(){…}; public static Boolean intertupted(){….};线程中断VS任务中断③Future.cancel()。中断只是个标记,线程不会主动去中断自己,需要自己处理中断。调用阻塞函数期间会抛出InterruptedException。处理InterruptedException:a)传递异常,使得你的方法也成为可中断的阻塞方法。b)恢复中断状态,从而是调用栈中的上层代码能够对其进行处理。
“一段来自http://book.51cto.com/art/200704/44732.htm”代码修改:
class MyThread extends Thread
{
public void run()
{
while(!isInterrupted()) // 无限循环,并使线程每隔1秒输出一次字符串
{
System.out.println(Thread.currentThread().getName());
System.out.println(getName()+" is running");
try{ sleep(1000);}
catch(InterruptedException e)
{
System.out.println(isInterrupted());
System.out.println(e.getMessage());
interrupt();
System.out.println(isInterrupted());
//break;
}
}
}
}
public class Cs
{
public static void main(String[] args) throws InterruptedException
{
MyThread m=new MyThread();
// 创建线程对象m
System.out.println(Thread.currentThread().getName());
System.out.println("Starting thread...");
m.start();
// 启动线程m
Thread.sleep(2000);
//主线程休眠2秒,使线程m一直得到执行
System.out.println("Interrupt thread...");
System.out.println(m.isInterrupted());
m.interrupt();
System.out.println(m.isInterrupted());
// 调用interrupt()方法中断线程m
Thread.sleep(2000);
// 主线程休眠2秒,观察中断后的结果
System.out.println("Stopping application..."); // 主线程结束
}
}
输出:
main
Starting thread...
Thread-0
Thread-0 is running
Thread-0
Thread-0 is running
Interrupt thread...
false
true
false
sleep interrupted
true
Stopping application...
④处理不可中断的阻塞:不是所有课阻塞方法或阻塞机制都能响应中断。对于不可中断操作而被阻塞的线程,可以使用类似于中断的手段来停止这些线程,但要求知道线程阻塞的原因,知道抛出那些异常,处理异常处理中断。【如:socket I/O,同步I/O,Selector异步I/O,获取某个锁】⑤使用newTaskFor封装非标准的取消:newTaskFor是ThreadPoolExecutor的一个用来生成RunnableFuture的工厂方法,RunnableFuture扩展Future和Runnable接口。可以由它改变Future.cancel方法行为。
4)停止基于线程的服务:对于持有线程的服务,只要服务的存在时间大于创建线程的方法的存在时间,那就应该提供生命周期方法关闭自己。
5)处理非正常的线程终止:导致线程提前死亡的最主要原因:RuntimeException。未捕获异常的处理:当一个线程由于未捕获异常而退出是,JVM会把这个事件报告给引用程序提供的UncaughtExceptionHandler异常处理器。
6)递归算法的并行化
7)GUI是单线程的:通过封闭机制来实现线程安全性。所有GUI对象,包括可视化组件和数据模型等,都只能在事件线程中访问。【单线程的GUI框架并不仅限于Java中,在Qt, NexiStep, MaxOS Cocoa, X Windows以及其他环境中的GUI框架都是单线程的。都是因为会发生竞态条件和死锁:表现在事件处理和MVC】
8)串行事件处理:事件是另一种类型的任务。AWT和Swing提供的事件处理机制在结构上也类似于Executor。SwingUtilities.invokeLater和SwingUtilities.invokeAndWait这两个方法的作用酷似Executor。可以将Swing的事件线程视为一个单线程的Executor
9)短时间GUI任务和长时间GUI任务【abstract class SwingWorker<T,V>:execute(), doInBackground, process(), done()】
======================================================================
活跃性、性能与测试:
1)死锁:锁顺序死锁、动态锁顺序死锁、协作对象之间发生的死锁、资源死锁
2)死锁的避免与诊断:①尽量减少潜在的加锁交互数量,将获取锁时需要遵循的协议写入正式文档并始终遵循这些协议;②通过两阶段策略:先找出在什么地方将获取多个锁(使这个集合尽量小),然后对所有这些实例进行全局分析,从而确保它们在整个程序中获取顺序都保持一致(数据库);③支持定时的锁;④通过线程转储信息来分析死锁;JVM通过线程转储的信息在锁的等待关系图中通过搜索循环来找出死锁。
3)其他活跃性危险:①饥饿:线程无法访问它所需要的资源而不能继续执行,【避免使用线程优先级,因为这会增加平台依赖性,并导致活跃性问题,在大多数并发应用程序中。都可以使用默认的线程优先级。JVM需要把Thread API中定义的优先级映射到操作系统的调度优先级,很有可能是不同Java优先级被映射到同一个优先级中】;②糟糕的响应性:长任务和短任务;不良的锁管理,长时间地占用锁;③活锁:该问题尽管不会阻塞线程,但也不能继续执行,因为线程将不断重复执行相同的操作,而且总会失败。【表现】:错误地将不可修复的错误作为可修复的错误;多个相互协作的线程都对彼此进行响应从而修改各种的状态,并使得任何一个线程都无法继续执行,类似让路问题。【解决办法】:在重试机制中引入随机性:等待随机长度的时间和回退(网络协议)。
4)Amdahl定律:在增加计算资源的情况下,程序在理论上能够实现最高加速比,这个值取决于程序中可并行组件与串行组件所占的比重。在所有并发称心中都包含了一些串行部分。
5)线程引入的开销:①上下文切换;②内存同步(可见性);③阻塞:竞争的同步,JVM在实现阻塞行为时,可以采用自旋等待(通过循环不断地尝试获取锁,直到成功)或者通过操作系统挂起被阻塞的线程。
6)减少锁的竞争:①减少锁的持有时间(缩小锁的范围:快进快出);②降低锁的请求频率(减小锁的粒度:锁分解和锁分段,避免热点域);③使用带有协调机制的独占锁(如:并发容器、读-写锁、不可变对象、原子变量),这些机制允许更高的并发性。
7)并发测试:①安全性测试:采用测试不变条件的形式,即判断某个类的行为是否与其他规范保持一致。②活跃性测试;③性能测试:吞吐量(一组并发任务中已完成任务所占的比例)、响应性(请求从发出到完成之间的时间,延迟)、可伸缩性(增加更多资源的情况下,吞吐量的提示情况)。
分享到:
相关推荐
这本书的读书笔记涵盖了多个关键知识点,旨在帮助读者深入理解Java并发编程的核心概念。 1. **线程和进程的区别** - **线程** 是程序执行的最小单位,一个进程中可以有多个线程同时执行,共享同一块内存空间,通信...
在Java并发编程中,数据的封装与访问控制、线程安全性的考量、同步机制的使用是重要的基础概念和技巧。以下是从给出的文件内容中提取出的详细知识点: 1. 数据封装与访问控制:确保内部私有数据不被轻易访问,并且...
《Java并发编程实战》个人读书笔记,非常详细: 1 简介 2 线程安全性 3 对象的共享 4 对象的组合 5 基础构建模块 6 任务执行 7 取消与关闭 8 线程池的使用 9 图形用户界面应用程序 10 避免活跃性危险 11 性能与可...
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括可见性、发布与逸出、线程封闭、不可变性、安全发布等内容
《java并发编程实战》读书笔记-第2章-线程安全性,脑图形式,使用xmind8制作 包括引言、线程安全性定义、原子性、加锁机制、使用锁保护状态、活跃性与性能等内容
这本"Java并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括线程安全类设计、实例封闭、线程安全性委托、现有线程安全类中添加功能和文档化同步策略等内容
### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 1. **不要跨线程访问共享变量:** 当多个线程共享某个变量时,若其中一个线程修改了该变量,其他线程若没有正确同步,则可能读取到错误的数据。...
│ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...
《java并发编程实战》读书笔记-第3章-对象的共享,脑图形式,使用xmind8制作 包括同步容器类、并发容器类、阻塞队列和生产者消费者模式、阻塞和中断方法、同步工具类。最后是构建高效且可伸缩的结果缓存
《Java并发编程的艺术》笔记 第一章 并发编程的挑战 第二章 Java并发机制的底层实现原理 volatile的两条实现原则: 1. Lock前缀指令会引起处理器缓存回写到内存 2. 一个处理器的缓存回写到内存会导致其他...
《Java并发编程实战》是一本深入探讨Java多线程和并发编程的经典著作,它为开发者提供了全面、实用的指导,帮助他们理解和解决并发问题。这本书的中文版使得更多的中国开发者能够受益于其丰富的知识和实践经验。 ...
Java语音项目的资源包括原生的JSAPI、开源库如CMU Sphinx和FreeTTS,商业化的服务如Google Cloud Speech-to-Text API,以及其他框架和工具。通过利用这些资源,您可以开发出功能强大的语音应用程序。Java语音项目的...
并发编程实战》阅读笔记 有关 Java 并发编程~ 别急别急,在重写它啦~,会补充一些新的内容进去,预计 2020/02 完成。 Content Java 并发编程基础 保证线程安全的两个角度 构造安全的并发应用程序 Java 并发高级主题 ...
《实战Java高并发程序设计》是一本专注于Java并发编程实践的书籍,试读版提供了前两章的内容,为读者提供了一个初步了解并发编程基础的窗口。在Java领域,并发编程是构建高性能、高效率系统的关键技术,对于软件开发...
"java高并发.txt"可能是一份文档或笔记,涵盖了Java并发编程的核心概念和技术。它可能详细解释了线程的生命周期、线程安全问题(如数据竞争、活锁、死锁)、并发工具类(如CountDownLatch、CyclicBarrier、Semaphore...
11. **案例分析与实战**:笔记可能包含实际的并发编程案例,帮助读者更好地将理论知识应用到实践中。 通过深入学习这份"Java并发实践-学习笔记",开发者能够提升自己在处理多线程和并发问题上的能力,从而设计出更...
Java并发编程学习笔记 本项目整理自《Java7并发编程实战手册》,感兴趣的话推荐阅读原著 本章内容包括: 线程的创建和运行 线程信息的获取和设置 线程的中断 线程中断的控制 线程的Hibernate和恢复 等待线程的终止 ...
综上所述,这一系列学习笔记涵盖了并发编程的关键概念和实战技巧,包括Java内存模型、线程池、并发容器的使用以及常见数据结构的线程安全问题。通过深入学习这些内容,开发者可以更好地理解和解决多线程环境下的编程...
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....