JAVA多线程系列-4-线程创建的4种方式

2016/05/25 Java

本章从实际代码出发,分析一下线程创建的4种方式:

  • Runnable
  • Thread
  • Callable
  • ExecutorService

希望读者最后能够明白4种方式的区别与联系,理解线程池管理的优势。

线程创建的4种方式

Runnable创建线程

这种是最常用,最基本的创建线程的方式。

Runnable是线程接口,通过实现Runnable接口,并重写run()方法,即可实现线程类,实例化后,通过start()方法启动线程。

public static void main(String[] args)
{	
	System.out.println(Thread.currentThread().getName()+" is Running");
	new Thread((new Create()).new  MyRunnable(),"线程1").start();
}

public class MyRunnable implements Runnable
{
	@Override
	public void run() {
		try {
			Thread.sleep(500);//单位ms
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+" is Running");
	}
}

Thread创建线程

Thread是线程类,是Runnable的一种实现。

所有的Runnable的实现都必须转化为Thread类,才能够启动!

public static void main(String[] args)
{	
	new Thread((new Create()).new  MyThread(),"线程2").start();
}

public class MyThread extends Thread
{
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+" is Running");
	}
}

创建有返回值的线程

Callable是类似Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务。 但是与Runnable不同的是,但是Callable创建的线程有返回值,用Future保存。 实现Callable的类需要重写call()方法。最后转换为FutureTask -> Thread(future) 通过start()启动线程, 或者通过线程池submit()方法启动!

public static void main(String[] args)
{
	Future<String> future1=pool.submit(new MyThread());
	try {
		Thread.sleep(100);
		System.out.println("返回值为:"+future1.get().toString());
	} catch (Exception e) {
		e.printStackTrace();
	}
}

public static class MyThread implements Callable <String>
{
	@Override
	public String call() throws Exception {

		return "我是返回值!";
	}
	
}

线程池管理线程

线程池为大量线程的同时运行提供环境,提供调度管理。 线程池通过接收上述3种方式创建的线程作为参数,进而以每个线程作为调度单位进行调度~

线程池的创建分2大类:

  • 1:单次运行
  • 2:周期调度

每一个又可以细分为3小类:

  • 1:单个线程调度
  • 2:n个线程调度
  • 3:自动调整大小的线程池
public static void main(String[] arg)
{
	//单次调度
//	ExecutorService pool=Executors.newSingleThreadExecutor();//单个线程的线程池
//	ExecutorService pool=Executors.newFixedThreadPool(2);//最大同时运行2个线程池
//	ExecutorService pool=Executors.newCachedThreadPool();//自动调整大小的线程池
			
	//周期调度线程
//	ScheduledExecutorService  pool=Executors.newSingleThreadScheduledExecutor();//单个周期线程的线程池
	ScheduledExecutorService  pool=Executors.newScheduledThreadPool(2);//2个周期线程的线程池
	
	pool.scheduleAtFixedRate(new Thread(new MyRunnable(),"t1"),1,1,TimeUnit.SECONDS);//设置调用周期
	
	pool.execute(new Thread(new MyRunnable(),"t1"));
	pool.execute(new Thread(new MyRunnable(),"t2"));
	pool.execute(new Thread(new MyRunnable(),"t3"));
//	pool.shutdown();
	System.out.println("hello");
}

public static class MyRunnable implements Runnable
{
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+" is Running");
	}
}

Runnable&Thread创建线程区别:

1:前者方便实现数据共享;
2:前者避免了Java单继承的局限性,可以继承多个接口。

上一章: 类&包等名词解释

下一章: 线程调度的6+6

Search

    Post Directory