结构化并发应用程序
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并发编程学习笔记"可能是作者在深入研究Java并发特性、工具和最佳实践过程中积累的心得体会。下面,我们将根据这个主题,探讨一些关键的Java并发编程知识点。 1. **线程与进程**:在多任务环境中,线程是...
│ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...
### Java并发编程实践笔记知识点详解 #### 一、保证线程安全的方法 1. **不要跨线程访问共享变量:** 当多个线程共享某个变量时,若其中一个线程修改了该变量,其他线程若没有正确同步,则可能读取到错误的数据。...
Java语音项目的资源包括原生的JSAPI、开源库如CMU Sphinx和FreeTTS,商业化的服务如Google Cloud Speech-to-Text API,以及其他框架和工具。通过利用这些资源,您可以开发出功能强大的语音应用程序。Java语音项目的...
并发编程实战》阅读笔记 有关 Java 并发编程~ 别急别急,在重写它啦~,会补充一些新的内容进去,预计 2020/02 完成。 Content Java 并发编程基础 保证线程安全的两个角度 构造安全的并发应用程序 Java 并发高级主题 ...
11. **案例分析与实战**:笔记可能包含实际的并发编程案例,帮助读者更好地将理论知识应用到实践中。 通过深入学习这份"Java并发实践-学习笔记",开发者能够提升自己在处理多线程和并发问题上的能力,从而设计出更...
Java并发编程学习笔记 本项目整理自《Java7并发编程实战手册》,感兴趣的话推荐阅读原著 本章内容包括: 线程的创建和运行 线程信息的获取和设置 线程的中断 线程中断的控制 线程的Hibernate和恢复 等待线程的终止 ...
综上所述,这一系列学习笔记涵盖了并发编程的关键概念和实战技巧,包括Java内存模型、线程池、并发容器的使用以及常见数据结构的线程安全问题。通过深入学习这些内容,开发者可以更好地理解和解决多线程环境下的编程...
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
Java并发编程是Java开发中的重要领域,特别是在大型分布式系统或者高并发应用中,对线程安全和性能优化的理解与实践至关重要。"JUC并发编程学习笔记(硅谷)"很可能包含了关于Java并发工具集(Java Util Concurrency, ...
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
Java开发实战经典全套笔记是李兴华老师针对Java初学者及进阶者精心编写的教程集合,涵盖了Java语言的核心概念、重要特性和实际应用。这些笔记以PDF格式提供,易于阅读,同时也支持打印,便于离线学习和长期保存。...
Java并发编程是编程领域中的重要组成部分,特别是在大型系统和服务器端开发中不可或缺。Java自诞生以来就内置了对多线程的支持,使得开发者能够轻松创建并行运行的任务,提升程序性能。然而,随着并发编程实践的深入...
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
Java互联网架构多线程并发编程原理及实战 视频教程 下载 1-1 课程简介.mp4 1-2 什么是并发编程.mp4 1-3 并发编程的挑战之频繁的上下文切换.mp4 1-4 并发编程的挑战之死锁.mp4 1-5 并发编程的挑战之线程安全....
异常处理是JAVA中的重要安全机制,集合框架是存储和操作数据的主要工具,IO流用于文件操作和数据传输,多线程则可以实现程序的并发执行,网络编程则是开发分布式应用的基础,反射提供了运行时动态操作类和对象的能力...
多线程和IO流则涉及并发编程和数据读写,对于高性能的Web应用至关重要。 其次,Java-Web笔记进一步讲解了Servlet、JSP、过滤器、监听器等Java Web开发的核心技术。Servlet是Java Web应用的基础,用于接收和响应HTTP...