0.引言
1.线程的创建方法
1.1.【继承Thread类,覆写run()方法】
public class ThreadIntroduction {
public static void main(String[] args)
{
for(int index=0;index<3;index++)
{
MyThread thread=new MyThread("just for a test");
thread.start();
}
}
}
class MyThread extends Thread
{
//自定义
private String description;
public MyThread(String description)
{
this.description=description;
}
@Override
public void run()
{
System.out.println(description);
for(int i=0;i<5;i++)
{
System.out.println(Thread.currentThread().getName()+": ["+i+"]");
}
}
}
某次运行结果
:
1.2.【实现Runnable接口】
public class ThreadIntroduction {
public static void main(String[] args)
{
for(int index=0;index<3;index++)
{
RunnableThread runnablethread=new RunnableThread("just for a Runnable Interface test");
//Runnable接口实现类对象作为Thread类的target,创建Thread类对象
new Thread(runnablethread).start();
}
}
}
class RunnableThread implements Runnable
{
//自定义
private String description;
public RunnableThread(String description)
{
this.description=description;
}
@Override
public void run()
{
System.out.println(description);
for(int i=0;i<5;i++)
{
System.out.println(Thread.currentThread().getName()+": ["+i+"]");
}
}
}
某次运行结果
:
1.3.【通过Callable接口和Future创建线程】
1. 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
2. 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
3. 使用FutureTask对象作为Thread对象的target创建并启动新线程。
4. 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值
public class ThreadIntroduction {
public static void main(String[] args)
{
//2.创建实现Callable的类的对象
MyCallableThread callablethread=new MyCallableThread();
//3.用FutureTask包装实现了Callable接口的类的对象
FutureTask<String> ft=new FutureTask<String>(callablethread);
//4.将包装后的对象作为target,创建Thread对象,并调用start
new Thread(ft).start();
try
{
System.out.println(Thread.currentThread().getName()+":"+ft.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
//1.创建实现Callable的类,并实现call方法
class MyCallableThread implements Callable<String>
{
@Override
public String call() throws Exception
{
for(int i=0;i<5;i++)
{
System.out.println(Thread.currentThread().getName()+": ["+i+"]");
}
return "just a test for Callable interface.";
}
}
某次运行结果
:
2.线程池
2.1 java线程池核心类ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
其参数的意义分别为:
2.2 线程池应用举例
public class MainClassForTest {
public static void main(String[] args)
{
int corePoolSize=2;
int maximumPoolSize=4;
long keepAliveTime=20;
TimeUnit unit=TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<Runnable>(2);
ThreadPoolExecutor pool =new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
keepAliveTime, unit, workQueue);
//创建6个任务,并将其加入到线程池中
for(int i=0;i<6;i++)
{
//创建自定义任务实例
MyRunnable task=new MyRunnable("ID["+i+"]");
//加入到线程池
pool.execute(task);
System.out.println("当前任务数量:"+pool.getTaskCount());
System.out.println("当前池中线程数量:"+pool.getPoolSize());
System.out.println("当前阻塞队列中任务数量:"+pool.getQueue().size());
}
}
}
/**
* 实现Runnable接口,创建自定义任务类MyRunnable
*/
class MyRunnable implements Runnable
{
private String id;
public MyRunnable(String id)
{
this.id=id;
}
@Override
public void run()
{
try{
Thread.sleep(1000L);
}catch( InterruptedException e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+id);
}
}
2.3.异常处理
(1) 默认的ThreadPoolExecutor.AbortPolicy:处理程序遭到拒绝将抛出运行时RejectedExecutionException;
(2) ThreadPoolExecutor.CallerRunsPolicy:线程调用运行该任务的 execute 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度
(3) ThreadPoolExecutor.DiscardPolicy:不能执行的任务将被删除;
(4) ThreadPoolExecutor.DiscardOldestPolicy :如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)。
在上面例子中加上一行代码,设置异常处理模式:
public static void main(String[] args)
{
int corePoolSize=2;
int maximumPoolSize=4;
long keepAliveTime=20;
TimeUnit unit=TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<Runnable>(2);
ThreadPoolExecutor pool =new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
keepAliveTime, unit, workQueue);
//设置异常处理模式
pool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//创建8个任务,并将其加入到线程池中
for(int i=0;i<8;i++)
{
//创建自定义任务实例
MyRunnable task=new MyRunnable("ID["+i+"]");
//加入到线程池
pool.execute(task);
System.out.println("当前任务数量:"+pool.getTaskCount());
System.out.println("当前池中线程数量:"+pool.getPoolSize());
System.out.println("当前阻塞队列中任务数量:"+pool.getQueue().size());
}
}
此外,我们也可以通过实现RejectedExecutionHandler接口,自定义异常处理;
class MyRejectedExecutionHandler implements RejectedExecutionHandler
{
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
{
// TODO Auto-generated method stub
}
}