第一章 Thread Management(线程管理) 下

来源:互联网 发布:c语言初级程序 编辑:程序博客网 时间:2024/05/17 05:15

涉及内容

  • 创建和运行一个线程
  • 获取和设置线程信息
  • 打断一个线程
  • 控制打断的线程
  • 休眠和唤醒线程
  • 等待线程的终止
  • 创建和运行守护线程
  • 处理线程中不受控制的异常
  • 使用local thread变量
  • 将线程加入组
  • 处理线程组的不受控制的异常
  • 通过工厂创建线程

1、使用local thread变量

线程之间共享变量或者不共享变量

例子:local thread 变量机制

外部变量

package com.jack;import java.util.Date;import java.util.concurrent.TimeUnit;public class UnsafeTask implements Runnable {private Date startDate;@Overridepublic void run() {startDate = new Date();System.out.printf("开始线程: %s : %s\n", Thread.currentThread().getId(),startDate);try {TimeUnit.SECONDS.sleep((int) Math.rint(Math.random()*10));}catch (InterruptedException e) {e.printStackTrace();}System.out.printf("线程完成: %s : %s\n", Thread.currentThread().getId(), startDate);}public static void main(String[] args) {UnsafeTask task = new UnsafeTask();for(int i=0; i< 10; i++){Thread thread= new Thread(task);thread.start();try{TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e){e.printStackTrace();}}}}

日志:



线程内部变量

import java.util.Date;import java.util.concurrent.TimeUnit;public class SafeTask implements Runnable{private static ThreadLocal<Date> startDate = new ThreadLocal<Date>(){@Overrideprotected Date initialValue() {return new Date();}};@Overridepublic void run() {System.out.printf("开始线程: %s : %s\n", Thread.currentThread().getId(),startDate.get());try {TimeUnit.SECONDS.sleep((int) Math.rint(Math.random()*10));}catch (InterruptedException e) {e.printStackTrace();}System.out.printf("线程完成: %s : %s\n", Thread.currentThread().getId(), startDate.get());}public static void main(String[] args) {SafeTask task = new SafeTask();for(int i=0; i< 10; i++){Thread thread= new Thread(task);thread.start();try{TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e){e.printStackTrace();}}}}

日志:


总结:

  • 1、ThreadLocal里面有initialValue()初始化方法、set()方法,get()方法,还有remove()方法(移除变量)
  • 2、ThreadLocal线程内私有

2、线程组

有多个线程为一组,一起控制。

例子:创建10个线程组,一起休眠,一起打断和测试

import java.util.Date;import java.util.Random;import java.util.concurrent.TimeUnit;public class SearchTask implements Runnable{private Result result;public SearchTask(Result result) {super();this.result = result;}@Overridepublic void run() {String name = Thread.currentThread().getName();System.out.printf("线程 %s: 开始\n", name);try{doTask();result.setName(name);} catch (InterruptedException e){System.out.printf("线程 %s: 打断了\n", name);return ;}System.out.printf("线程 %s: 结束\n", name);}private void doTask() throws InterruptedException {Random random = new Random((new Date()).getTime());int value = (int) (random.nextDouble()*100);System.out.printf("线程 %s: %d\n", Thread.currentThread().getName(), value);TimeUnit.SECONDS.sleep(value);}public static void main(String[] args) {ThreadGroup threadGroup = new ThreadGroup("Searcher");Result result = new Result();SearchTask searchTask = new SearchTask(result);for(int i=0; i<5; i++){Thread thread = new Thread(threadGroup, searchTask);thread.start();try{TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e){e.printStackTrace();}}System.out.printf("线程的数量:%d\n", threadGroup.activeCount());System.out.printf("关于线程组的信息\n");threadGroup.list();//判断处于活跃的线程Thread[] threads =new Thread[threadGroup.activeCount()];//将线程threads复制到ThreadGroup当中threadGroup.enumerate(threads);for (int i=0; i<threadGroup.activeCount(); i++){System.out.printf("线程=== %s: %s \n", threads[i].getName(),threads[i].getState());}waitFinish(threadGroup);threadGroup.interrupt();}private static void waitFinish(ThreadGroup threadGroup) {while(threadGroup.activeCount() >4) {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e){e.printStackTrace();}}}}
日志:


总结:

  • 1.创建一个线程组,将线程加入组当中
  • 2、每个线程进行休眠100秒以下
  • 3、查看当前的线程的状态都是Time-Waiting
  • 4、threadGroup.interrupted()将所有线程打断。

3、处理线程组的异常

public class MyThreadGroup extends ThreadGroup {public MyThreadGroup(String name) {super(name);}@Overridepublic void uncaughtException(Thread t, Throwable e) {System.out.printf("线程 %s 已经抛出异常\n",t.getId());e.printStackTrace(System.out);System.out.printf("终结剩下的线程\n");interrupt();}}

import java.util.Random;public class Task implements Runnable{@Overridepublic void run() {int result;Random random = new Random(Thread.currentThread().getId());while(true){result = 1000/ ((int)(random.nextDouble()*1000));System.out.printf("%s : %f\n", Thread.currentThread().getId(), result);if(Thread.currentThread().isInterrupted()){System.out.printf("%d : 打断了\n" ,Thread.currentThread().getId());return ;}}}public static void main(String[] args) {MyThreadGroup threadGroup = new MyThreadGroup("MyThreadGroup");Task task = new Task();for(int i=0; i<2; i++) {Thread t = new Thread(threadGroup, task);t.start();}}}

总结:

  • 1、创建一个自定义线程组,重写非检查异常
  • 2、System.out.printf("%s : %f\n", Thread.currentThread().getId(), result);  这里 %f抛出异常,然后被线程组捕获了。
  • 3、选择处理异常处理器,本线程异常处理-》本组线程异常处理-》默认处理。


4、通过工厂创建线程

通过ThreadFactory接口创建线程对象。

import java.util.ArrayList;import java.util.Date;import java.util.Iterator;import java.util.List;import java.util.concurrent.ThreadFactory;public class MyThreadFactory implements ThreadFactory {private int counter;private String name;private List<String> stats;public MyThreadFactory(String name) {super();this.counter = 0;this.name = name;this.stats = new ArrayList<String>();}@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r, name +"-Thread_" + counter);counter++;stats.add(String.format("创建线程 %d 名称为:%s,时间: %s\n", t.getId(), t.getName(), new Date()));return t;}public String getStats(){StringBuffer buffer = new StringBuffer();Iterator<String> it = stats.iterator();while (it.hasNext()) {buffer.append(it.next());buffer.append("\n");}return buffer.toString();}}
import java.util.concurrent.TimeUnit;public class Task implements Runnable{@Overridepublic void run() {try{TimeUnit.SECONDS.sleep(1);}catch (InterruptedException e){e.printStackTrace();}}public static void main(String[] args) {MyThreadFactory factory = new MyThreadFactory("MyThreadFactory");Task task = new Task();Thread thread;System.out.printf("开始一个线程\n");for (int i=0; i<10; i++){thread = factory.newThread(task);thread.start();}System.out.printf("工厂的stats:\n");System.out.printf("%s\n", factory.getStats());}}

总结:

1、可以统一管理线程,比如限制线程的数量

2、分析线程的数据状态

第一章完结。。。。。

原创粉丝点击