主函数:

package com.thread;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class WorkThreadSample {
	public static void main(String args[]) throws InterruptedException {
		// 任务List: 15个任务
		List workList = new ArrayList();
		for (int i = 0; i < 4; i++) {
			workList.add(new Work("任务" + i));
		}
		// 执行任务的线程:3个
		for (int i = 0; i < 3; i++) {
			WorkThread thread = new WorkThread(workList, "线程" + i);// 线程名,需要什么参数可以向里面传递。
			thread.start();// 启动线程
		}

		/*
		 * 睡眠6秒后,线程已经执行完毕,这时候会发现刚刚运行的线程已经没有了, 所以,线程在执行完run方法后,JVM会自动回收处理。
		 * 不用我们手动释放。
		 * 将下面的代码注释注释掉,可以看到线程在执行完run方法后,就自动回收了,已经没有Thread-0,Thread-1,Thread-2 了。
		 */
//		new Thread().sleep(6000);
//		/**
//		 * 在Java的文档中为我们提供了Thread类的完整文档
//		 */
//		// 在Thread对象中取得所有的线程所在的栈,然后取得Set对象,便利取得所有的线程
//		Iterator iterator = Thread.getAllStackTraces().keySet().iterator();
//		Thread myThread = null;
//		while (iterator.hasNext()) {
//			Thread t = (Thread) iterator.next();
//			System.err.println("=========iterator.next():" + t.getName());
//			boolean alive = t.isAlive();
//			System.out.println(t+"的状态为:" + alive);
//			// 根据线程名取得自己想要的线程
//			if (t.getName().equals("Thread-1") && alive) {
//				myThread = t;
//				System.err.println("===线程名,优先级,线程组=======:" + myThread.toString());
//				break;
//			}
//		}
		
		
	}
}


业务类:

package com.thread;

public class Work {
	// 任务名
	private String name = null;

	public Work(String name) {
		this.name = name;
	}

	// 任务内容
	public void work(String worker) {
		try {
			new Thread().sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	    System.out.println(worker + "线程:" + name + "结束!");
	}
}


线程类:

package com.thread;

import java.util.List;

public class WorkThread extends Thread{
	 // 线程名
    public String name = null;
    // 任务List
    private List workList = null;
    public WorkThread(List workList, String name) {
		this.name = name;
		this.workList = workList;
	}

	public void run() {
        System.out.println(name + " 线程开始执行...");
        while (true) {
        	  Work work = null;
        	  {//同步代码块
		            // 同步锁,放在循环里是不让该线程一直占用workList
		        	synchronized (workList) {
		                // 任务List中有任务时进行循环
		                if (workList != null && !workList.isEmpty()) {
		                    // 取得一个任务,并从任务List中删除该任务
		                    work = workList.remove(0);
		                   // System.out.println("------------"+workList.size());
		                } else {
		                    // 所有任务都完成
		                    break;
		                }
		            }
		        	/**
		        	 * 注意这里不能放在synchronized 中,否则就只能一个一个 的执行了,达不到多线程并发的需求,所以讲业务放到外面,用一个同步代码块包裹,这样就运行更快。
		        	 *  执行任务,例:
		        	 */
		            work.work(name);
        	  }
        }
        System.out.println(name+"执行完成");
    }
}


运行结果为:

线程1 线程开始执行...
线程2 线程开始执行...
线程0 线程开始执行...
线程2线程:任务1结束!
线程0线程:任务2结束!
线程1线程:任务0结束!
线程2线程:任务3结束!
线程0线程:任务4结束!
线程1线程:任务5结束!
线程1线程:任务8结束!
线程2线程:任务6结束!
线程0线程:任务7结束!
线程1执行完成
线程0执行完成
线程2线程:任务9结束!
线程2执行完成

总结:


①线程创建是消耗一定资源的,所以不能创建太多线程。

②线程执行完run方法后,会自动回收。

③我们对线程上锁,只锁最重要的东西,唯一的东西,不可重复的。其他不用上锁,用同步代码块就可以了。

④每个线程的执行时间不一样长,有的快,有的慢。

⑤线程运行后要跳出while(true) 循环,否则会一直运行。


2017年1月22日17:11:14