java线程创建和启动

创建一个线程可以有3中方法:

1.继承Thread类  2.实现Runnable接口  3.实现Callable接口  第1种和第2种不会有返回值,第3种可以有返回值.

class NewThread1 extends Thread{
	//重写run方法
	public void run(){
		System.out.println("this is a new thread1");
	
	}
}

class NewThread2 implements Runnable{
	private static int taskCount = 0;
	private final int taskNo = taskCount++;
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("before:newthread2 No is"+taskNo);
		Thread.yield();
		System.out.println("after:newthread2 No is"+taskNo);
	}
	
}

class NewThread3 implements Callable<String>{

	@Override
	public String call() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("this is a new thread3");
		return "thread3 result";
	}
	
}

根据不同的线程任务创建方法的不同,启动线程的方法也有差别主要分为2种:Thread类的start()方法,使用java.util.concurrent包中的执行器Executor。

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//使用线程的start方法,适合实现Runable或者是继承Thread的任务
		NewThread1 newThread1 = new NewThread1();
		newThread1.start();
		
		Thread thread2  = new Thread(new NewThread2());
		thread2.start();
				
		//使用执行器Executor,适合实现了Runable的任务
		ExecutorService exec = Executors.newCachedThreadPool();
//		ExecutorService exec = Executors.newFixedThreadPool(5);
//		ExecutorService exec = Executors.newSingleThreadExecutor();
		
		for(int i = 0;i<5;i++){
			exec.execute(new NewThread2());
		}
		
		//使用ExecutorService.submit()方法启动实现callable的任务
		Future<String> fs;
		fs = exec.submit(new NewThread3());
		try {
			System.out.println("newThread3 out:"+fs.get());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		exec.shutdown();
	}

        利用start()方法,对于继承Thread和实现Runnable的任务都适合,注:如果是调用run(),就是单纯的函数调用,是在main方法的线程中执行run方法。

        实现Runnable接口的任务也可以利用执行器executor来启动线程。常用的执行器有3类:CachedThreadPool(),FixedThreadPool(int), SingleThreadExecutor().3种都可以来启动多个线程,主要的差别是:CachedhThreadPool为每一个任务创建一个线程,来了任务才分配线程资源,FixedThreadPool一次性的执行固定的线程资源分配,代价高,但是节省时间。一般情况下建议使用CachedThreadPool。SingleThreadExecutor类似参数为1的FixedThreadPool,另一个区别是向SingleThreadExecutor提交多个任务时,这些任务将会排队,一个任务完全执行完后才会下一个任务,其他2个执行器不会,当有多个任务提交形成多个线程时,任务结果是乱序的。

        实现Callable接口的任务只能用submit来启动线程,返回的是一个Future<V>类型的结果,带有泛型V。利用方法get()可以取出结果的值。

CachedThreadPool执行结果图:


使用CachedThreadPool运行newThrad2. 5个线程是乱序的。并且每次执行的结果都会不会一样。


SingleThreadExecutor执行结果图:



使用SingleHhreadExecutor执行newthread2时。即使有yield()使该线程放弃CPU,但是提交的5个任务是依次完成。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值