第一章 Thread Management(线程管理) 上
2017-08-11 16:05
337 查看
涉及内容:
创建和运行一个线程获取和设置线程信息
打断一个线程
控制打断的线程
休眠和唤醒线程
等待线程的终止
创建和运行守护线程
处理线程中不受控制的异常
使用local thread变量
将线程加入组
处理线程组的不受控制的异常
通过工厂创建线程
1、简介
并发(concurrency):多线程运行在单核处理器,执行顺序--无序并行(parallelism) :多线程运行在多核处理,执行顺序--有序
2、创建和运行一个线程
创建一个线程的方法:继承Thread类
实现Runnable接口,然后创建以Runable对象为参数的Thread对象
这个例子将会使用实现Runnable接口来实现多线程,创建和运行10个线程。每个线程计算和打印一到十的乘积。
public class Calculator implements Runnable{
private int number;
public Calculator(int number) {
super();
this.number = number;
}
public void run() {
for(int i=1; i <= 10; i++){
System.out.printf("%s: %d * %d = %d\n",
Thread.currentThread().getName(),number,i,i*number);
}
}
public static void main(String[] args) {
for(int i=1; i<=10; i++){
Calculator calculator = new Calculator(i);
Thread thread = new Thread(calculator);
thread.start();
}
}
}日志:
总结:
1、当调用start()方法将会创建一个执行线程
2、只要一个线程调用System.exit(),所有线程结束,程序终止
2、获取和设置线程的信息
线程的属性:ID: 唯一标识每个线程
Name: 线程的名称
Priority:线程的优先级(从1到10) 最低1,最高10。不在这个范围会抛出异常
Status : 线程的状态(六种状态:创建,运行,阻塞,等待,时间等待,终止)
例子:创建十个线程,并设置它的优先级和名称,然后展示它的状态信息。当然它也会计算乘积。
package com.jack;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.Thread.State;
public class Calculator implements Runnable{
private int number;
public Calculator(int number) {
super();
this.number = number;
}
public void run() {
for(int i=1; i <= 10; i++){
System.out.printf("%s: %d * %d = %d\n",
Thread.currentThread().getName(),number,i,i*number);
}
}
public static void main(String[] args) throws IOException {
Thread [] threads = new Thread[10];
Thread.State [] status = new Thread.State[10];
for (int i=0; i<10; i++){
threads[i] = new Thread(new Calculator(i));
if((i % 2) == 0) {
threads[i].setPriority(Thread.MAX_PRIORITY);
} else {
threads[i].setPriority(Thread.MIN_PRIORITY);
}
threads[i].setName("Thread " + i);
}
try (FileWriter file = new FileWriter("D:\\\\\\data\\log.txt");
PrintWriter pw = new PrintWriter(file);){
for (int i=0; i<10; i++) {
pw.println("Main: Status of Thread " + i + " : " +
threads[i].getState());
status[i] = threads[i].getState();
}
for (int i=0; i<10; i++){
threads[i].start();
}
boolean finish = false;
while(!finish) {
for (int i=0; i<10; i++) {
if (threads[i].getState() != status[i]) {
writeThreadInfo(pw, threads[i], status[i]);
status[i] = threads[i].getState();
}
}
finish = true;
//判读所有线程是否结束
for(int i=0; i<10; i++) {
finish = finish && (threads[i].getState() == State.TERMINATED);
}
}
}
}
private static void writeThreadInfo(PrintWriter pw, Thread thread, State state) {
pw.printf("Main : Id %d - %s\n", thread.getId(), thread.getName());
pw.printf("Main : Priority: %d\n", thread.getPriority());
pw.printf("Main : Old State: %s\n", state);
pw.printf("Main : New State : %s\n", thread.getState());
pw.printf("Main : *********************************\n");
}
}
日志:
总结:
1、打印状态语句块不一定是10整数倍,因为在执行打印状态的时候程序线程,有些状态没有第二次没有改变而被过滤了。
2、循环打印状态直到所有线程都终止,这里用了FileWriter(注意要确认文件夹是否存在,否则抛出异常)和PrintWriter
3、并不是优先级高一定先执行完,只是有概率是靠前的。
4、不能修改ID和status属性。
5、线程默认值的名称为Thread-XX(XX是一个数字)
3、打断一个线程
创建一个线程,通过interruption mechanism(打断机制)5秒之后将会强迫finalization。public class PrimeGenerator extends Thread{
@Override
public void run() {
long number = 1L;
while(true) {
if (iPrime(number)) {
System.out.printf("数字 %d 是 素数 \n", number);
}
if(isInterrupted()){
System.out.printf("素数生成器已经打断了");
return;
}
number ++;
}
}
private boolean iPrime(long number) {
if(number <=2 ) {
return true;
}
for (long i=2; i<number; i++){
if((number % i) == 0){
return false;
}
}
return true;
}
public static void main(String[] args){
Thread task = new PrimeGenerator();
task.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e){
e.printStackTrace();
}
task.interrupt();
}
}
日志:
总结:
1、生成数字越大,说明你计算机计算能力越强,哈哈
2、interrupt()方法将会设置属性为true,而isInterrupted()方法只是返回这个属性的值。
3、interrupt()是static 方法, isInterrupted()不是static方法
4、控制线程的打断情况
实现用确定的名称在文件夹以及子目录下查找文件来学习InterruptedException异常的控制import java.io.File;
import java.util.concurrent.TimeUnit;
public class FileSearch implements Runnable{
private String initPath;
private String fileName;
public FileSearch(String initPath, String fileName) {
super();
this.initPath = initPath;
this.fileName = fileName;
}
@Override
public void run() {
File file = new File(initPath);
if(file.isDirectory()) {
try{
directoryProcess(file);
} catch (InterruptedException e){
System.out.printf("%s: 搜索已经被中断了", Thread.currentThread().getName());
}
}
}
private void directoryProcess(File file) throws InterruptedException {
File list[] = file.listFiles();
if(list != null) {
for (int i=0; i <list.length; i++) {
if(list[i].isDirectory()) {
directoryProcess(list[i]);
}else {
fileProcess(list[i]);
}
}
}
if(Thread.interrupted()) {
throw new InterruptedException();
}
}
private void fileProcess(File file) throws InterruptedException {
if(file.getName().equals(fileName)) {
System.out.printf("%s : %s\n", Thread.currentThread().getName(),file.getAbsolutePath());
}
if(Thread.interrupted()) {
throw new InterruptedException();
}
}
public static void main(String[] args) {
FileSearch sercher = new FileSearch("D:\\360Downloads", "filelist.dat");
Thread thread = new Thread(sercher);
thread.start();
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}
总结:
1、如果在10秒内找完所有文件和目录将不会抛出异常(不管找到文件有没有)。
2、InterruptedException抛出与一些API方法有关例如,sleep()
3、学习新的休眠方法,TimeUnit类的方法。
4、利用递归查询文件夹与文件。
相关文章推荐
- 第一章 Thread Management(线程管理) 中
- 第一章 Thread Management(线程管理) 下
- Java 线程第三版 第一章Thread导论、 第二章Thread的创建与管理读书笔记
- ARM官方《CMSIS-RTOS教程》之线程的管理和优先级Thread Management and Priority
- Java 线程第三版 第一章Thread导论、 第二章Thread的创建与管理读书笔记
- 线程管理(Thread Management)
- Java 线程第三版 第一章Thread导论、 第二章Thread的创建与管理读书笔记
- HandlerThread线程管理
- C# ThreadPool 自定义线程管理池 实现多线程池管理 有助与开发多线程系统的线程运行情况监控。
- 线程管理 ACE_Thread_Manager
- ACE线程管理---ACE_Thread_Manager
- 第一章线程管理
- 操作系统的线程管理机制以及Thread.Sleep()的作用
- 《Fundamentals of Project Management 4th Edition》读书笔记 第一章 项目管理总览
- boost::thread线程管理
- 线程(二)Thread Management
- Java 螺纹第三版 第一章Thread介绍、 第二章Thread创建和管理学习笔记
- (一)线程管理_10---Thread Group中处理不可控制的异常
- Java7并发编程指南——第一章:线程管理
- 接口 ThreadMXBean 一个很好用的线程管理接口类 可以参考 jdk 帮助文档