java 自定义线程池+示例代码

目录

原理

示例代码

自定义线程池:

测试类:


原理

自定义线程池的原理很简单,一共三个,一个是线程同步问题,一个是线程通信,另一个我认为最核心的原理没有官方的名字,我把它叫做线程与run()的分离,有关线程同步的介绍请看这里,有关线程通信的介绍及示例代码请看这里

关于线程与run()的分离,回想多线程的三种实现方法:继承Thread类,实现Runable接口,或者是匿名类(包括Thread匿名类和Runable匿名类),把我们想执行的代码告诉线程的方法,都是重写run方法。看下面这段代码

 

			Runnable task=new Runnable() {
				@Override
				public void run() {
                                    ....
			};

                        Thread t=new Thread(task).start();

这样的代码相信很多人都写过,并没有多高深的地方,但是我在理解线程池的时候想到了这段代码,这里体现了一个思想:线程是线程,run方法是run方法。它俩是可以分开的。

如果我们把Runable的一个实例叫做一个任务,那么我们也可以说,线程和任务是可以分开的。

线程池的核心思想就是线程与任务的分离,先启动几个线程进入wait状态,等有任务的时候通知一个线程来领任务,领到任务的线程执行任务的run方法,执行完再进入wait状态。这样就是可以重复利用线程的线程池了。

为了好理解,我们把一个Runable的实例作为一个任务,java自带的线程池ThreadPoolExecutor也是用Runable的实例作为任务的,但实际是在我们自定义的线程池里,我们可以自己定义任务对象和任务方法(可以不用叫run())。为了方便,下面的实例代码都还是用的Runnable。

示例代码

自定义线程池:

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

public class MyThreadPool {
	int size;
	List<Runnable> tasks=new ArrayList<Runnable>();
	
	public MyThreadPool(int size) {
		this.size=size;
		
		for(int i=0;i<size;i++)
			new ConsumeThread("线程"+i).start();
	}
	
	public void addTask(Runnable task)
	{
		synchronized(tasks)
		{
			tasks.add(task);
			tasks.notify();
		}
	}
	
	private class ConsumeThread extends Thread{
		public ConsumeThread(String name) {
			super(name);
		}
		@Override
		public void run() {
			while(true)
			{
				Runnable task = null;
				//竞争tasks
				synchronized(tasks)
				{
					System.out.println(this.getName()+"占有tasks");
						try {
							//如果tasks为空,则进入休眠状态
							if(tasks.isEmpty())
							{
								System.out.println(this.getName()+"进入休眠状态");
								tasks.wait();
								//被唤醒后跳出这轮循环重写检测tasks是否为空
								continue;
							}
							//tasks不为空,取出一个任务开始执行
							task=tasks.remove(0);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
				}
				//取出一个任务就释放tasks,否则任务在synchronized(tasks)内执行的话,任务执行期间,其他任务就不能被其他线程取出执行。
				if(task!=null)
					task.run();
					//任务执行结束,继续竞争tasks执行任务直到任务池为空
			}
		}
	}
	
}

测试类:
 

public class MyThreadPoolTest {
	public static void main(String[] args) {
		MyThreadPool tp=new MyThreadPool(5 );
		for(int i=0;i<100;i++)
		{
			Runnable task=new Runnable() {
				@Override
				public void run() {
					try {
						//假设这是执行一个任务所用时间
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println("\t\t\t任务执行完毕");
				}
			};
			tp.addTask(task);
		}

	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值