Java线程和并发工具是应用开发中的重要部分,备受开发者的重视,也有一定的学习难度。《JAVA线程与并发编程实践》是针对Java 8中的线程特性和并发工具的快速学习和实践指南。
《JAVA线程与并发编程实践》共8章,分别介绍了Thread 类和Runnable 接口,同步,等待和通知,线程组、定时器框架、井发工具、同步器、锁框架,以及高级并发工具等方面的主题。每章的来尾都以练习题的方式,帮助读者巩固所学的知识。附录A给出了所有练习题的解答,附录B给出了一个基于Swing线程的教程。

Thread和Runnable

Java程序是通过线程执行的,线程在程序中具有独立的执行路径。当多条线程执行时,它们彼此之间的路径可以不同。举个例子,一条线程可能在执行switch语句的某个case分支,另一条线程很可能在执行其他case分支。每个Java应用程序都有一个执行main( )函数的默认主线程。应用程序也可以创建线程在后台操作时间密集型任务,以确保对用户的响应。这些封装了代码执行序列的线程对象就被称为runnable.Java虚拟机给每条线程分配独立的JVM栈空间以免彼此干扰。独立的栈使得线程可以追踪它们自己下一条要执行的指令,这些指令会依线程不同而有所区别。栈空间也为每条线程单独准备了- 份方法参数、局部变量以及返回值的拷贝。Java主要是通过java. lang. Thread类以及java. lang. Runnable接口

Thread和Runnable简介
Thread类为底层操作系统的线程体系架构提供一套统一接口 (操作系统通常负责创建和管理线程)。单个的操作系统线程和一个Thread对象关联。

Runnable接口为关联Thread对象的线程提供执行代码。这些代码放在Runnable的void run( )方法中,这个方法虽然不接收任何参数且没有返回值,但是有可能抛出异常。

1.1 创建 Thread和Runnable对象

除了默认主线程,线程都是通过创建合适的Thread和Runnable对象进入应用程序的。Thread类声明了几个构造方法来初始化Thread对象。其中有几个构造方法需要接收Runnable对象作为参数。我们有两种方式创建Runnable 对象。第一种方式是创建一个实现了Runnable接口的匿名类,如下:

Runnable r m new Runnable()

{

@Override

public void run()

// perform some work

System. out . println( “Hello from thread”);

}

};

在Java8之前,这是唯一一种 创建runnable的方式。不过,Java 8引入lambda表达式更为快捷地创建runnable:Runnable r = () -> System. out . print1n(“Hello from thread”);lambda确实比匿名类更简洁。我会在本章及随后的章节继续使用这些语言特性。

1.2 获取和设置线程的名称

每个Thread对象都会被赋予一一个名称, 这样有利于调试。这个名称如果不是显式指定的,那么默认会以一个Thread-作为前缀。你可以通过调用Thread的String getName()方法来获取这个名称。若要设置名称,则得把名称传递给一个合适的构造函数,如Thread(Runnable r, String name),或者调Thread的void setName (String name)方法。如下面的代码片段所示:

Thread t1 = new Thread(r, “thread t1”); .

System. out.println(t1.getName()); // Output: thread t1

Thread t2■new Thread®;

t2. setName(“thread t2”);

System. out.println(t2. getName()); // Output: thread t2

1.3 获取一条线程的执行状态

线程的执行状态由Thread . State枚举常量标识:

●NEW:该状态下线程还没有开始执行。

●RUNNABLE:该状态下线程正在JVM中执行。

●BLOCKED:该状态下线程被阻塞并等待一个监听锁(我会在第2章中介绍监听锁)。

●WAITING: 该状态下线程无限期地等待另外一条线程执行特定的操作。

●TIMED_ WAITING: 该状态下线程在特定的时间内等待另外一条线程执行某种操作。

●TERMINATED:该状态下线程已经退出。

Thread通过提供Thread . State getState()方法来让应用程序判断线程的当前状态。示例如下:

Thread t = new Thread®;

System. out. println(t.getState()); // output: NEW

《JAVA线程与并发编程实践》:并发工具类和Executor框架
并发工具类和Executor框架
2.1 并发工具类简介

Java对底层线程操作的支持使得你可以创建多线程应用程序。这些程序比对应的单线程程序提供了更好的性能和响应能力。尽管如此,依然存在一一些问题:

●低级的并发原语, 比如synchronized和wait()、notify()经常难以正确使用。对这些原语的误用会导致竞态条件、线程饿死、死锁和其他风险,这些风险都很难侦测和调试。

●太过依赖 synchronized原语会带来性能问题,这些问题会影响应用程序的可扩展性,对于诸如Web服务器之类的高度线程化的应用程序而言,后果会很严重。

●开发 者经常需要高级的线程结构,如线程池和信号量。Java对底层线程操作的支持中不包含这些结构,开发者被迫构建一套自己的结构,这样不仅耗时还容易出错。为了解决这些问题,Java5引入了并发工具类,这是一个由强大且易扩展的高性能线程工具类组成的框架,包含了线程池和阻塞队列。该框架由下列包中的多种类型组成。

●; java.util.concurrent: 经常在并发编程当中使用的工具类, 如:executors。

●java. util. concurrent.atomic: 支持在单个变量上进行无锁且线程安全操作的工具类。

●java.util. concurrent. locks: 在某些条件上(这类对象会暂停执行“等待”线程直到被其他线程唤醒,此时对象的一些布尔型状态可能变为true)获取锁和执行等待的工具类。通过这些类型进行锁或等待操作比通过Java基于***的同步以及等待、唤醒机制具有更好的性能和伸缩性。这个框架也将longnanoTime( )方法引入了类java.1ang.System中,这让你做相对时间测量的时候可以访问纳秒级别的时间资源。并发工具类可以被分类为executor、同步器( synchronizer)以及锁框架等。我会在接下来的章节探讨executor并在后续章节讨论其余类别。

《JAVA线程与并发编程实践》:并发工具类和Executor框架
总结
本书适合有一定基础的Java程序员阅读学习,尤其适合想要掌握Java线程和并发工具的读者阅读参考。