创建线程的三种方式总结

1、方法 1: 覆盖Thread类的run方法,Thread类本身 implements Runnable;如下演示代码:

package com.tiger.practice;
/**
 * 方法 1: 覆盖Thread类的run方法,Thread类本身 implements Runnable
 * 优点:1、编程难度低
 *       2、直接继承Thread 复写run方法
 *       3、直接可以start
 *       4、可以方便获取线程属性,name[getName();],线程id[getId();] 
 *       
 * 缺点:局限性-->不能再继承其他类
 * @author tiger
 * @Date 2017年7月24日
 */
public class FirstThreadDemo extends Thread{
	public static void main(String[] args) throws Throwable {
		/*--------------------子线程  start--------------------*/
		MyThread1 th1 = new MyThread1();
		th1.start();
		
		MyThread2 task = new MyThread2();//创建任务体
		Thread th2 = new Thread(task);
		Thread th3 = new Thread(task);
		th2.start();
		th3.start();
		//开启使用线程
		task.start();
		/*--------------------子线程  end--------------------*/
		
		/*--------------------主线程  start--------------------*/
		for (int i = 0; i < 20; i++) {
			System.out.println("主线程 - 执行第[" + i+"]次");
			Thread.sleep(10);
		}
		/*--------------------主线程  end--------------------*/
	}
}
/**
 * 局限性 : 不能再继承其他类
 * @author tiger
 * @Date 2017年7月24日
 */
class MyThread1 extends Thread{//局限性不能再继承其他类
	//复写run方法,是一个任务执行体,调用start方法,会自动调用run,会自动启动线程。
	public MyThread1(String name) {
		super(name);
	}
	public MyThread1() { }
	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			System.out.println(getName()+ " 执行第[" + i+"]次");
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
/**
 * 测试两个线程共用一个任务体。
 * @author tiger
 * @Date 2017年7月24日
 */
class MyThread2 extends Thread{//局限性不能再继承其他类
	int num;
	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			System.out.println("Thread-1 执行第[" + i+"]次");
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

2、方法 2 :任务执行体 implements Runnable;如下演示代码:

package com.tiger.practice;
/**
 * 方法 2 :任务执行体 implements Runnable
 * 
 * 优点:1、如果只是定义任务执行体,就选用Runnable这种。
 * 
 * 缺点:1、获取线程的属性不方便。      
 * @author tiger
 * @Date 2017年7月24日
 */
public class TwoThreadDemo extends Thread{

	public TwoThreadDemo(Runnable runnable) {
		super( runnable );
	}
	public TwoThreadDemo() { }

	public static void main(String[] args) throws Throwable {
		/*--------------------子线程  start--------------------*/
		TwoThreadDemo th1 = new TwoThreadDemo(new Task());
		th1.start();
		
		//创建 2 个线程共用一个任务体(共享同一份资源)task2 ?
		Task2 task2 = new Task2();
		Thread th2 = new Thread(task2);
		Thread th3 = new Thread(task2);
		th2.start();
		th3.start();
		/*--------------------子线程  end--------------------*/
		
		/*--------------------主线程  start--------------------*/
		for (int i = 0; i < 10; i++) {
			System.out.println("主线程 - 执行第[" + i+"]次");
			Thread.sleep(20);
		}
		/*--------------------主线程  end--------------------*/
	}
}
/**
 * 定义一个任务执行体
 * @author tiger
 * @Date 2017年7月24日
 */
class Task implements Runnable{
	//覆盖run方法
	@Override
	public void run() {
		//在任务体中获取当前线程属性
		Thread thread = Thread.currentThread();
		try {
			for (int i = 0; i < 10; i++) {
				System.out.println("子线程 1 执行第[" + i+"]次" + thread.getName());
				Thread.sleep(50);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
/**
 * 定义另一个任务执行体
 * @author tiger
 * @Date 2017年7月24日
 */
class Task2 implements Runnable{
	//覆盖run方法
	@Override
	public void run() {
		Thread thread = Thread.currentThread();
		try {
			for (int i = 0; i < 10; i++) {
				System.out.println("子线程 2 执行第[" + i+"]次"+ thread.getName());
				Thread.sleep(50);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

3、方法 3 :任务执行体 implements Callable,是为了获取线程返回值而设计;只有在需要获取返回值时才用次方法。如下演示代码:

package com.tiger.practice;

import java.util.concurrent.*;
/**
 * 方法 3 :任务执行体 implements Callable,是为了获取线程返回值而设计。
 *          只有在需要获取返回值时才用次方法。
 * 
 * 优点:1、是一个增强型的任务体。
 *       2、可以获取线程的返回值。
 *       3、可以终止任务的执行。
 *       4、探知线程执行情况。
 *       
 * 缺点:1、变成较为复杂。
 * @author tiger
 * @Date 2017年7月24日
 */
public class ThreeThreadDemo {
	public static void main(String[] args) throws InterruptedException {
		/*--------------------子线程  start--------------------*/
//		MyTask task = new MyTask();
		FutureTask<Integer> ft = new FutureTask<Integer>( new MyTask());
		Thread th = new Thread(ft,"线程1");
		th.start();
		/*--------------------子线程  end----------------------*/
		
		/*--------------------主线程  start----------------------*/
		for( int i=1; i<=50; i++ ){
			System.out.println("主线程 - 执行第[" + i+"]次");
			Thread.sleep( 3 );
		}
		try {
			//主线程阻塞在此, 等那一个线程执行完
//			System.out.println("sum = "+ft.get());
			
//			等那一个线程,如果等了 1 ms 还未返回结果,则终止等待。防止线程堵塞。
			System.out.println( "sum = "+ ft.get( 1, TimeUnit.SECONDS ));
			//终止取消任务执行
			boolean cancel = ft.cancel(true);
			//获取执行状态
			boolean ret = ft.isDone();
			while (!ret){
				ret = ft.isDone();
				System.out.println("子线程运行状态 : "+ret);
				Thread.sleep( 15 );
			}
			System.out.println("cancel : "+cancel);
			System.out.println("探测子线程是否完成 : "+ret);
			
		}catch (InterruptedException e) {//被打断异常
			e.printStackTrace();
		} catch (ExecutionException e) {//被执行异常
			e.printStackTrace();
		} 
		catch (TimeoutException e) {
			System.out.println( "主线程中 获取返回值超时." );
		}
		/*--------------------主线程  end----------------------*/
	}
}

/**
 * 定义一个任务执行体 implements Callable
 * @author tiger
 * @Date 2017年7月24日
 */
class MyTask implements Callable <Integer> {
	//重写call方法
	@Override
	public Integer call() throws Exception {
		Integer sum = 0;
		for( int i=1; i<=50; i++ ){
			sum += i;
			System.out.println("子线程 1 执行第[" + i+"]次");
			Thread.sleep( 20 );
		}
		return sum;
	}
}
以上几种创建方式各有特点,见代码注释。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ljt-tiger

thanks

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值