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

本文介绍了线程管理的各种技巧,包括使用ThreadLocal变量确保线程间数据隔离、创建线程组进行批量操作、处理线程异常及通过工厂模式创建线程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

涉及内容

  • 创建和运行一个线程
  • 获取和设置线程信息
  • 打断一个线程
  • 控制打断的线程
  • 休眠和唤醒线程
  • 等待线程的终止
  • 创建和运行守护线程
  • 处理线程中不受控制的异常
  • 使用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;

	@Override
	public 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>(){
				@Override
				protected Date initialValue() {
					return new Date();
				}
	};
	
	@Override
	public 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;
	}

	@Override
	public 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);
	}

	@Override
	public 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{

	@Override
	public 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>();
	}

	@Override
	public 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{

	@Override
	public 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、分析线程的数据状态

第一章完结。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值