已阅读5页,还剩37页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
目录前言第一章: 线程管理1. 介绍2. 线程的创建和运行3. 获取和设置线程信息4. 线程的中断5. 操作线程的中断机制6. 线程的睡眠和恢复7. 等待线程的终结8. 守护线程的创建和运行9. 处理线程的不受控制异常10. 使用本地线程变量11. 线程组12. 处理线程组内的不受控制异常13. 用线程工厂创建线程第二章 : 基本线程同步1. 介绍2. 同步方法3. 在同步的类里安排独立属性4. 在同步代码中使用条件5. 使用Lock来同步代码块6. 使用读/写锁来同步数据访问7. 修改Lock的公平性8. 在Lock中使用多条件第三章: 线程同步工具1. 介绍2. 控制并发访问一个资源3. 控制并发访问多个资源4. 等待多个并发事件完成5. 在一个相同点同步任务6. 运行并发阶段性任务7. 控制并发阶段性任务的改变8. 在并发任务间交换数据第四章: 线程执行者1. 介绍2. 创建一个线程执行者3. 创建一个大小固定的线程执行者4. 执行者执行返回结果的任务5. 运行多个任务并处理第一个结果6. 运行多个任务并处理所有的结果7. 在延迟后执行者运行任务8. 执行者定期的执行任务9. 执行者取消任务10. 执行者控制一个结束任务11. 执行者分离运行任务和处理结果12. 执行者控制被拒绝的任务第五章: Fork/Join 框架1. 介绍2. 创建 Fork/Join 池3. 加入任务的结果4. 异步运行任务5. 任务中抛出异常6. 取消任务第六章:并发集合1. 介绍2. 使用非阻塞线程安全列表3. 使用阻塞线程安全列表4. 用优先级对使用阻塞线程安全列表排序5. 使用线程安全与带有延迟元素的列表6. 使用线程安全的导航地图7. 生成并行随机数8. 使用原子变量9. 使用原子阵列第七章: 定制并发类1. 介绍2. 定制ThreadPoolExecutor 类3. 实现一个优先级制的执行者类4. 实现ThreadFactory接口来生成自定义线程5. 在执行者对象中使用我们的 ThreadFactory6. 在计划好的线程池中定制运行任务7. 实现ThreadFactory接口来生成自定义线程给Fork/Join框架8. 在Fork/Join框架中定制运行任务9. 实现一个自定义锁类10. 实现一个基于优先级传输Queue11. 实现你自己的原子对象第八章: 测试并发应用程序1. 介绍2. 监控锁接口3. 监控Phaser类4. 监控执行者框架5. 监控Fork/Join池6. 编写有效的日志7. FindBugs分析并发代码8. 配置Eclipse来调试并发代码9. 配置NetBeans来调试并发代码10. MultithreadedTC测试并发代码前言当你用计算机工作的时候,你在同时做多样事情。你可以边听音乐边写文档边读取邮件。你可以这样做的原因是你的操作系统运行并发任务。并发编程是关于 基础与进程的一个 提供多任务或者程序同时运行还相互沟通来交换数据和相互同步的平台。Java是一个并发平台,在Java程序中提供很多执行并发任务的类。每个版 本,Java提升了促进程序员开发并发程序的功能。这本书包含了在Java版本7的并发API中最重要和最有用的技巧,所以你可以直接在你的应用程序中使 用的,以下这些: 基本线程管理 线程同步机制 执行者代表的线程的创建与管理 Fork/Join框架来提高应用程序的性能 并发程序的数据结构 按照需要来调整一些并发类的默认行为 测试Java的并发应用程序这本书包含了什么第一章, 线程管理会教读者怎样创建线程的基本操作。线程的创建,运行,和状态的管理都会用基本例子来讲解。第二章, 基本的线程同步会教读者使用低级别Java 进程来同步代码。锁和同步的关键词都会详讲。第三章, 线程同步实用程序讲教读者使用高等级的Java来管理线程之间的同步。它包括了怎样使用新Java 7 Phaser类来把同步任务分成段。第四章, 线程执行者将教读者用执行者代表来管理线程。他们允许并发任务的运行,管理和获取结果。第五章, Fork/Join框架将教读者使用新 Java 7 Fork/Join 框架. 它是一种特别的执行者面向执行被分治技术分成小的任务。第六章, 并发集合将教读者怎样使用一些Java语言提供的并发数据结构。并发程序必须使用这些数据结构来避免在它们的实现中使用同步代码块。第七章, 定制并发类将教读者怎样根据需求来改编Java并发API中一些特别有用的类。第八章, 测试并发应用程序将教读者怎样获取Java 7 并发API中最有用的结构状态信息。读者还会学习怎样使用免费的工具来调试并发应用,例如,用Eclipse, NetBeans IDE, or FindBugs程序来侦查可能存在的漏洞。 介绍在计算机世界,当人们谈到并发时,它的意思是一系列的任务在计算机中同时执行。如果计算机有多个处理器或者多核处理器,那么这个同时性是真实发生的;如果计算机只有一个核心处理器那么就只是表面现象。现代所有的操作系统都允许并发地执行任务。你可以在听音乐和浏览网页新闻的同时阅读邮件。我们说这种并发是进程级别的并发。而且在同一进程内,也会同时有多种任务。这些在同一进程内运行的并发任务称之为线程。另一个与并发性有关的内容是并行性。并行性与并发性有着不同的定义但有一定相关的联系。有些人是这样认为:当在一个单核处理器上使用 多个线程执行应用程序时,很明显的,在程序执行的同时你就会明白这是并发性。当你使用多个线程在多核处理器或者多处理器的计算机上执行应用时,便是并行 性。还有人这样认为:当使用没有预定顺序的多线程执行应用程序时,它是并发性。而当使用多种按照顺序来执行的线程来简化一个问题的解决方案时,它是并行 性。这个章节会展示一些关于如何使用Java 7 API 来实现最基本的线程操作方法。你将会知道如何在Java程序中创建和运行线程,如何控制它们的执行,以及如何通过把线程分组然后把它们作为一个整体来操控。 线程的创建和运行在这个指南中,我们将学习如何在Java程序中创建和运行线程。与每个Java语言中的元素一样,线程是对象。在Java中,我们有2个方式创建线程: 通过直接继承thread类,然后覆盖run()方法。 构建一个实现Runnable接口的类, 然后创建一个thread类对象并传递Runnable对象作为构造参数在这个指南中,我们将使用第二种方法来制作一个简单的程序,它能创建和运行10个线程。每一个线程能计算和输出1-10以内的乘法表。准备 指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。怎么做呢按照这些步骤来实现下面的例子:1. 创建一个名为Calculator的类,这个类要实现Runnable接口。public class Calculator implements Runnable 2. 声明一个名为number 的private int为属性,然后实现构造函数并初始化其值。private int number;public Calculator(int number) this.number=number;3. 实现run()方法. 这方法是给我们创建的线程执行指令,所以这个方法将计算数字乘法表。Overridepublic void run() for (int i=1; i=10; i+) System.out.printf(%s: %d * %d = %dn,Thread.currentThread().getName(),number,i,i*number);4. 现在, 实现程序的Main类。创建一个名为 Main的类并包含 main() 方法.public class Main public static void main(String args) 5. 在 main() 方法内,创建一个迭代10次的for循环。在每次循环中,创建一个 Calculator 类的对象, 一个Thread类的对象, 然后传递 Calculator 对象作为thread类构造函数的参数,最后调用线程对象的start() 方法。for (int i=1; i=10; i+) Calculator calculator=new Calculator(i); Thread thread=new Thread(calculator); thread.start();6. 运行程序并观察不同的线程是如何并行工作的。它是怎么工作的接下来是部分的程序输出的裁图。我们可以查看全部创建的线程,并行地运行, 见下图:每个Java程序最少有一个执行线程。当你运行程序的时候, JVM运行负责调用main()方法的执行线程。当调用Thread对象的start()方法时, 我们创建了另一个执行线程。在这些start()方法调出后,我们的程序就有了多个执行线程。当全部的线程执行结束时(更具体点,所有非守护线程结束时),Java程序就结束了。如果初始线程(执行main()方法的主线程)运行结束,其他 的线程还是会继续执行直到执行完成。但是如果某个线程调用System.exit()指示终结程序,那么全部的线程都会结束执行。创建一个Thread类的对象不会创建新的执行线程。同样,调用实现Runnable接口的 run()方法也不会创建一个新的执行线程。只有调用start()方法才能创建一个新的执行线程。更多在介绍这个指南时我们提到还有另一种方法可以创建新的执行线程。你可以实现一个类,这个类扩展Thread类并覆盖它的run()方法。接着,你就可以从这个类创建一个对象并调用start()方法来创建一个新的执行线程。参见 第一章,线程管理:通过创建工厂创建线程线程管理(二)获取和设置线程信息声明:本文是 Java 7 Concurrency Cookbook 的第一章, 作者: Javier Fernndez Gonzlez 译者:郑玉婷校对:欧振聪获取和设置线程信息Thread类的对象中保存了一些属性信息能够帮助我们来辨别每一个线程,知道它的状态,调整控制其优先级。 这些属性是: ID: 每个线程的独特标识。 Name: 线程的名称。 Priority: 线程对象的优先级。优先级别在1-10之间,1是最低级,10是最高级。不建议改变它们的优先级,但是你想的话也是可以的。 Status: 线程的状态。在Java中,线程只能有这6种中的一种状态: new, runnable, blocked, waiting, time waiting, 或 terminated.在这个指南里,我们将开发一个为10个线程设置名字和优先级的程序,然后展示它们的状态信息直到线程结束。这些线程会计算数字乘法表。准备指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。怎么做呢按照这些步骤来实现下面的例子:1. 创建一个类名为 Calculator,这个类一定要实现Runnable接口。1public class Calculator implements Runnable 2. 声明一个名为number的private int为属性,然后实现类的构造函数并初始化其值。1private int number;2public Calculator(int number) 3this.number=number;43. 实现方法run()。此方法是给我们创建的线程执行下达指令的,所以这个方法将计算并且打印数字乘法表。1Override2public void run() 3for (int i=1; i=10; i+)4System.out.printf(%s: %d * %d = %dn,Thread. currentThread().getName(),number,i,i*number);564. 现在, 实现应用的主类。创建一个名为Main的类,并包含 main() 方法.1public class Main 2public static void main(String args) 5. 创建一个大小为10的Thread类的数组和一个大小为10的Thread.State数组来保存将要执行的线程和它们的状态。1Thread threads=new Thread10;2Thread.State status=new Thread.State10;6. 创建10个Calculator类的对象,每个初始为不同的数字,然后分别用10个线程来运行它们。把其中5个的优先值设为最高,把另外5个的优先值为最低。1for (int i=0; i10; i+)2threadsi=new Thread(new Calculator(i);3if (i%2)=0)4threadsi.setPriority(Thread.MAX_PRIORITY);5 else 6threadsi.setPriority(Thread.MIN_PRIORITY);78threadsi.setName(Thread +i);97. 创建一个 PrintWriter对象用于把线程状态的改变写入文档。1try (FileWriter file = new FileWriter(.datalog.txt); PrintWriter pw = new PrintWriter(file);)8. 把10个线程的状态写入文档。现在,它成为NEW.1for (int i=0; i10; i+)2pw.println(Main : Status of Thread +i+ : +threadsi.getState();3statusi=threadsi.getState();49. 开始执行这10个线程.1for (int i=0; i10; i+)2threadsi.start();310. 直到这10个线程执行结束,我们会一直检查它们的状态。如果发现它的状态改变,就把状态记入文本。01boolean finish=false;02while (!finish) 03for (int i=0; i10; i+)04if (threadsi.getState()!=statusi) 05writeThreadInfo(pw, threadsi,statusi);06statusi=threadsi.getState();07080910finish=true;11for (int i=0; i10; i+)12finish=finish & (threadsi.getState()=State.TERMINATED);131411. 实现一个方法 writeThreadInfo(),这个方法写线程的 ID, name, priority, old status, 和 new status。1private static void writeThreadInfo(PrintWriter pw, Thread thread, State state) 2pw.printf(Main : Id %d - %sn,thread.getId(),thread.getName();3pw.printf(Main : Priority: %dn,thread.getPriority();4pw.printf(Main : Old State: %sn,state);5pw.printf(Main : New State: %sn,thread.getState();6pw.printf(Main : *n);712. 运行这个例子,然后打开 log.txt 文档并查看10个线程的状态变化。它是如何工作的接下来是程序在执行的log.txt文本的一些行的裁图。在这个文本中,可以发现有高优先级的线程们比低优先级的先结束。还可以发现线程状态的演变过程。程序的控制台显示的是线程计算的乘法表,而log.txt文本记录的是不同线程的状态演变。这样子,可以更好的观察线程的演变过程。Thread 类有能保存使用线程信息的属性。JVM根据线程的优先级来选择将使用CPU的线程,然后再根据每个线程的情况来实现它们的状态。如果你没有声明一个线程的名字,那么JVM会自动命名它为:Thread-XX,XX是一个数字。线程的ID或者状态是不可修改的。Thread类没有实现setId()和setStatus()方法来允许修改它们。更多在这个指南中,你学习了如何使用Thread对象来访问线程的属性信息。你也可以实现Runnable接口来访问这些信息。你可以用Thread类的静态方法currentThread()来访问正在运行的Runnable 对象的 Thread对象。你必须知道 setPriority() 方法会抛出 IllegalArgumentException 异常,如果你设置的优先级不是在1-10之间。参见 第一章,线程管理:线程的中断 线程管理(三)线程的中断 声明:本文是 Java 7 Concurrency Cookbook 的第一章, 作者: Javier Fernndez Gonzlez 译者:郑玉婷 校对:欧振聪 线程的中断 一个多个线程在执行的Java程序,只有当其全部的线程执行结束时(更具体的说,是所有非守护线程结束或者某个线程调用System.exit() 方法的时候),它才会结束运行。有时,你需要为了终止程序而结束一个线程,或者当程序的用户想要取消某个Thread对象正在做的任务。 Java提供中断机制来通知线程表明我们想要结束它。中断机制的特性是线程需要检查是否被中断,而且还可以决定是否响应结束的请求。所以,线程可以忽略中断请求并且继续运行。 在这个指南中, 我们将开发一个程序,它创建线程,然后在5秒之后,它会使用中断机制来强制结束线程。 准备 指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。 怎么做呢 按照这些步骤来实现下面的例子:: 1. 创建一个名为PrimeGenerator的类,扩展Thread类。1public class PrimeGenerator extends Thread 2. 覆盖 run()方法,写一个无限循环的while循环。在循环里,我们将从1开始处理连续的数字。对于每个数字,如果它是质数,那么,我们就把它写入到操控台。1Override2public void run() 3long number=1L;4while (true) 5if (isPrime(number) 6System.out.printf(Number %d is Prime,number);7 3. 处理完一个数字, 调用isInterrupted()方法来检查线程是否被中断了。如果它返回值为真,就写一个信息并结束线程的运行。1if (isInterrupted() 2System.out.printf(The Prime Generator has been Interrupted);3return;45number+;67 4. 实现isPrime()方法. 它返回 boolean 值表明接收到的数字是否是质数。01private boolean isPrime(long number) 02if (number =2) 03return true;040506for (long i=2; inumber; i+)07if (number % i)=0) 08return false;091011return true;12 5. 现在, 实现一个名为Main的类,包括实现main()方法来实现例子的Mian类。1public class Main 2public static void main(String args) 6. 创建并开始一个PrimeGenerator类的对象。1Thread task=new PrimeGenerator();2task.start(); 7. 等待5秒,然后中断 PrimeGenerator 方法。1try 2Thread.sleep(5000);3 catch (InterruptedException e) 4e.printStackTrace();56errupt(); 8. 运行并查看结果。 它是如果工作的 下面是以上例子的运行结果这截图。我们可以发现 PrimeGenerator 线程是如何检测到它被中断了然后写了信息并结束运行的。 请看截图: Thread 类还有一个boolean类型的属性来表明线程是否被中断。当你调用线程的interrupt() 方法,就代表你把这个属性设置为 true。 而isInterrupted() 方法仅返回属性值。 更多 Thread 类还有其他可以检查线程是否被中断的方法。例如,这个静态方法interrupted()能检查正在运行的线程是否被中断。 isInterrupted()和interrupted() 方法有着很重要的区别。 第一个不会改变interrupted属性值,但是第二个会设置成false。 interrupted() 方法是一个静态方法,建议使用isInterrupted()方法。 在之前提到的,线程是可以忽略中断指令的,但是并这不是我们所期望的行为。 线程管理(四)操作线程的中断机制声明:本文是 Java 7 Concurrency Cookbook 的第一章, 作者: Javier Fernndez Gonzlez 译者:郑玉婷 校对:欧振聪操作线程的中断机制在之前的指南里,你学习了如何中断执行线程和如何对Thread对象的中断控制。之前例子中的机制可以很容易中断的线程中使用。但是如果线程实现的 是由复杂的算法分成的一些方法,或者它的方法有递归调用,那么我们可以用更好的机制来控制线程中断。为了这个Java提供了 InterruptedException异常。当你检测到程序的中断并在run()方法内捕获,你可以抛这个异常。在这个指南中, 我们将实现的线程会根据给定的名称在文件件和子文件夹里查找文件,这个将展示如何使用InterruptedException异常来控制线程的中断。准备指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。怎么做呢按照这些步骤来实现下面的例子::1. 创建一个名为FileSearch的类,并一定要实现Runnable接口。1public class FileSearch implements Runnable 2. 声明2个为private的属性,一个是为了我们要查找的文件名和另一个是为了初始文件夹。为这个类实现一个构造函数,并初始化这些属性。1private String initPath;2private String fileName;3public FileSearch(String initPath, String fileName) 4this.initPath = initPath;5this.fileName = fileName;63. 为FileSearch类实现run()方法。 它会检测fileName属性是不是路径,如果它是,就调用processDirectory()方法。这个方法会抛出一个InterruptedException异常,所以我们应该要捕获它。01Override02public void run() 03File file = new File(initPath);04if (file.isDirectory() 05try 06directoryProcess(file);07 catch (InterruptedException e) 08System.out.printf(%s: The search has been interrupted,Thread.currentThread().getName();0910114. 实现 directoryProcess()方法。这个方法会获取文件夹的文件和子文件夹并处理他们。对于每个路径,这个方法会传递路径作为参数来循环调用。对 于每个文件,它会调用fileProcess()方法。处理完全部的文件和文件夹后,它会检查线程有没有被中断,在这个例子,会抛出一个 InterruptedException异常。01private void directoryProcess(File file) throws02InterruptedException 03File list = file.listFiles();04if (list != null) 05for (int i = 0; i list.length; i+) 06if (listi.isDirectory() 07directoryProcess(listi);08 else 09fileProcess(listi);10111213if (Terrupted() 14throw new InterruptedException();15165. 实现 processFile()方法。这方法会比较文件的名字与我们要搜索的文件名。如果他们一样,就写一条信息到控制台。比较完后,线程会检查有没有被中断,在这里,它会抛出一个InterruptedException异常。1private void fileProcess(File file) throws InterruptedException23if (file.getName().equals(fileName) 4System.out.printf(%s : %sn,Thread.currentThread().getName() ,file.getAbsolutePath();56if (Terrupted() 7throw new InterruptedException();896. 现在, 让我们来实现例子的主类吧。实现一个Main类并包含main()方法。1public class Main 2public static void main(String args) 7. 创建并初始一个FileSearch类的对象和一个执行它的任务的线程。然后,开始执行线程。1FileSearch searcher=new FileSearch(C:,autoexec.bat);2Thread thread=new Thread(searcher);3thread.start();8. 等10秒然后中断线程。1try 2TimeUnit.SECONDS.sleep(10);3 catch (InterruptedException e) 4e.printStackTrace();56errupt();79. 运行例子并查看结果。它是怎么工作的下面的截图给出了例子的执行结果。你可以发现FileSearch对象是如何执行的,当它检测到它被中断时。请看裁图:在这个例子, 我们使用Java异常来控制线程的中断。当你运行这个例子,程序开始浏览文件夹来检查他们是否含有那个文件。例如,如果你输入bcd,那么程序会循 环调用3次processDirectory()方法。当它检测到被中断时,它会抛出InterruptedException异常并继续执行方法,无论 已经多少次循环调用。更多InterruptedException 异常是由一些与并发API有关的Java方法,如sleep()抛出的。参见 第一章,线程管理:线程的中断指南线程管理(五)线程的睡眠和恢复声明:本文是 Java 7 Concurrency Cookbook 的第一章, 作者: Javier Fernndez Gonzlez 译者:郑玉婷 校对:欧振聪线程的睡眠与恢复有时, 你会感兴趣在一段确定的时间内中断执行线程。例如, 程序的一个线程每分钟检查反应器状态。其余时间,线程什么也不做。在这段时间,线程不使用任何计算机资源。过了这段时间,当JVM选择它时,线程会准备好 继续执行。为达此目的,你可以使用Thread类的 sleep() 方法 。此方法接收一个整数作为参数,表示线程暂停运行的毫秒数。 在调用sleep() 方法后,当时间结束时,当JVM安排他们CPU时间,线程会继续按指令执行,另一种可能是使用一个有TimeUnit列举元素的sleep() 方法,使用线程类的 sleep() 方法让当前线程睡眠,但是它接收的参数单位是表示并转换成毫秒的。在这个指南中, 我们将开发一个程序使用sleep()方法来每秒写入真实的日期。准备指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。怎么做呢按照这些步骤来实现下面的例子::1. 创建一个类名为 FileClock,并一定实现Runnable接口。public class FileClock implements Runnable 2. 实现 run() 方法。Overridepublic void run() 3. 写一个10次循环的环。在每次循环,创建一个Date对象,写入文本并调用TimeUnit 类有SECONDS属性的sleep()方法来暂停线程1秒的运行。根据这个值,线程会停止将近一秒。当然 sleep() 方法 可以抛出一个 InterruptedException 异常,我们要加入捕捉代码。被中断时,解放或关闭正在使用的线程资源是好习惯。for (int i = 0; i 10; i+) System.out.printf(%sn, new Date(); try TimeUnit.SECONDS.sleep(1); catch (InterruptedException e) System.out.printf(The FileClock has been interrupted); 4. 我们已经实现了线程。 现在,让我们来实现例子的主类吧。创建一个类名为 FileMain ,包含 main() 方法。public class FileMain public static void main(String args) 5. 创建FileClock类的对象并让一个线程执行它。然后,开始执行线程。FileClock clock=new FileClock();Thread thread=new Thread(clock);thread.start();6. 在主线程调用TimeUnit类有SECONDS属性的 sleep() 方法来等待5秒。try TimeUnit.SECONDS.sleep(5); catch (InterruptedException e) e.printStackTrace();7. 中断 FileClock 线程。errupt();8. 运行例子并查看结果。它是怎么工作的当你运行这个例子,你可以发现程序是如何每秒写入一个Date对象的,然后,有信息显示FileClock线程被中断。当你调用sleep()方法, Thread 离开CPU并在一段时间内停止运行。在这段时间内,它是不消耗CPU时间的,使用可以执行其他任务。当 Thread is是睡眠和中断的时候,那方法会立刻抛出InterruptedException异常并不会一直等到睡眠时间过去。更多Java 并发 API 有另一种方法能让线程对象离开 CPU。它是 yield() 方法, 它向JVM表示线程对象可以让CPU执行其他任务。JVM 不保证它会遵守请求。通常,它只是用来试调的。 线程管理(六)等待线程的终结声明:本文是 Java 7 Concurrency Cookbook 的第一章, 作者: Javier Fernndez Gonzlez 译者:郑玉婷 校对:方腾飞等待线程的终结在某些情况下,我们需要等待线程的终结。例如,我们可能会遇到程序在执行前需要初始化资源。在执行剩下的代码之前,我们需要等待线程完成初始化任务。为达此目的, 我们使用Thread 类的join() 方法。当前线程调用某个线程的这个方法时,它会暂停当前线程,直到被调用线程执行完成。在这个指南中, 我们将学习用初始化例子来使用这个方法。准备指南中的例子是使用Eclipse IDE 来实现的。如果你使用Eclipse 或者其他的IDE,例如NetBeans, 打开并创建一个新的java项目。怎么做呢按照这些步骤来实现下面的例子::1. 创建一个类名为 DataSourcesLoader 并一定实现Runnable接口。public class DataSourcesLoader implements Runnable 2. 实现run()方法。 它写信息来表明它开始运行,然后睡眠4秒,最后再写信息表明它结束运行。Overridepublic void run() System.out.printf("Beginning data sources loading: %sn",new Date();try TimeUnit.SECONDS.sleep(4); catch (InterruptedException e) e.printStackTrace(); System.out.printf("Data sources loading has finished:%sn",new Date();3. 创建一个类名为 NetworkConnectionsLoader 并一定要Runnable接口。实现run()方法。它将与DataSourcesLoader类的run()方法一样,但是它会睡眠6秒。4. 现在, 创建一个类名为 Main,包含 main()方法。public class Main public static void main(String args) 5. 创建一个 DataSourcesLoader 类对象并让线程运行它。DataSourcesLoader dsLoader = new DataSourcesLoader(); Thread thread1 = new Thread(dsLoader,"DataSourceThread");6. 创建一个 NetworkConnectionsLoader 类的对象并让线程运行它。NetworkConnectionsLoader ncLoader = new NetworkConnectionsLoader();Thread thread2 = new Thread(ncLoader,"NetworkConnectionLoad er");7. 让2个线程对象都调用 start() 方法。thread1.start();thread2.start();8. 2个线程都使用 join() 方法等待终结。 此方法可以抛出InterruptedException 异常, 所以要包含捕捉代码。try thread1.join(); thread2.join(); catch (InterruptedException e) e.printStackTrace();9. 写一条信息表明程序结束。System.out.printf("Main: Configuration has been loaded: %sn",new Date();10. 运行程序并查看结果。它是怎么工作的当你运行这个程序时,你可以发现2个线程对象都开始他们的执行。首先, DataSourcesLoader 结束它的运行。然后, NetworkConnectionsLoader 类结束它的运行,同时,主线程对象继续运行并写下了最后的信息。更多Java 提供2种形式的 join() 方法: join (long milliseconds) join (long milliseconds, long nanos)第一种join() 方法, 这方法让调用线程等待特定的毫秒数。例如,如果thread1对象使用代码thread2.join(1000), 那么线程 thread1暂停运行,直到以下其中一个条件发生: thread2 结束运行 1000 毫秒过去了当其中一个条件为真时,join() 方法返回。第二个版本的 join() 方法和第一个很像,只不过它接收一个毫秒数和一个纳秒数作为参数。 线程管理(七)守护线程的创建和运行声明:本文是 Java 7 Concurrency Cookbook 的第一章, 作者: Javier Fernndez Gonzlez 译者:郑玉婷 校对:方腾飞守护线程的创建和运行Java有一种特别的线程叫做守护线程。这种线程的优先级非常低,通常在程序里没有其他线程运行时才会执行它。当守护线程是程序里唯一在运行的线程时,JVM会结束守护线程并终止程序。根据这些特点,守护线程通常用于在同一程序里给普通线程(也叫使用者线程
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 图形旋转 课件
- 科学树叶 课件
- 双星轮胎 课件
- 人教版老王课件
- 幼儿园小班音乐《袋鼠妈妈》课件
- 西京学院《英汉口译》2023-2024学年第一学期期末试卷
- 物理课件变阻器
- 不锈钢抛光性能差的原因
- 西京学院《包装设计》2021-2022学年第一学期期末试卷
- 西华师范大学《植物地理学》2022-2023学年第一学期期末试卷
- 落实企业安全生产主体责任三年行动重点任务清单分解
- 部编版七年级上册语文阅读高频考点解析与突破课件
- 《初中英语写作》课件
- DB37-T 5202-2021 建筑与市政工程基坑支护绿色技术标准
- 《学会感恩与爱同行》PPT主题班会课件
- 牙科手机的清洗消毒、灭菌及保养课件
- 人音版二年级下册音乐《小蜜蜂》课件
- 新生入学适应教育课件
- 打印版医师执业注册健康体检表(新版)
- 湘教版八年级美术上册工作计划
- 高渗性非酮症糖尿病昏迷培训课件
评论
0/150
提交评论