线程的创建

Java使用Thread类代表线程

有三种方法可以创建一个线程


1.继承Thread类

定义一个Thread类的子类并重写run()方法

run()方法的方法体就是线程需要完成的任务,称作线程执行体

创建该类的实例即创建了线程对象


2.实现Runnable接口

定义一个类实现Runnable接口并重写run()方法

run()方法仍然是线程执行体

该类的实例本身并不是线程

将该类的实例作为Thread类创建对象的参数

由Thread类创建的对象才是真正的线程对象


3.实现Callable接口

定义一个类实现Callable接口并重写call()方法

call()方法作为线程执行体,且call()有返回值

创建一个FutureTask类对象封装该类对象的call方法

该类的实例及FutureTask类对象本身并不是线程

将FutureTask类的对象作为Thread类创建对象的参数

由Thread类创建的对象才是真正的线程对象


三种方式的对比

后两种方式的区别在于第三种方式定义的方法有返回值,并且可以声明抛出异常,其余基本相同

第一种方式与后两种的比较如下:


第一种方式

优点:

    实现简单,由于直接继承Thread类,需要访问当前线程只需要使用this

缺点:

    继承了Thread类,不能再继承其他父类


后两种方式

优点:

    只是实现了接口,还可以继承其他的父类

    多个线程对象可以共享同一个Runnable实现类的对象或Callable实现类的对象

确定:

    实现相对复杂,需要访问当前线程必须使用Thread.currentThread()方法


//继承Thread类
public class FirstThread extends Thread{
	private int i=0;
	@Override
//	重写run方法,run是线程执行体
	public void run(){
		for(; i<10; ++i)
//			Thread类的getName()方法返回该线程的名字
			System.out.println(getName()+" "+i);
	}
	
	public static void main(String[] args){
		new FirstThread().start();
		new FirstThread().start();
	}
}

//实现Runnable接口
public class SecondThread implements Runnable {
	private int i=0;
	@Override
//	重写run方法,run仍是线程执行体
	public void run() {
		for(; i<100; ++i)
			System.out.println(Thread.currentThread().getName()+" "+i);
	}
	
	public static void main(String[] args){
		SecondThread st = new SecondThread();
		new Thread(st).start();
		new Thread(st).start();
	}
}

//实现Callable接口
public class ThirdThread implements Callable<Integer>{
	private int i=0;
	@Override
//	重写call方法,作为线程执行体
	public Integer call(){
		for(; i<1000; ++i)
			System.out.println(Thread.currentThread().getName()+" "+i);
		return i;
	}
	
	public static void main(String[] args){
		ThirdThread tt = new ThirdThread();
//		FutureTask封装了Callable对象的call方法
		FutureTask<Integer> task = new FutureTask<Integer>(tt);
		FutureTask<Integer> task2 = new FutureTask<Integer>(tt);
//		FutureTask对象作为Thread创建对象的参数
		new Thread(task).start();
		new Thread(task2).start();
		try{
		System.out.println(task.get());
		} catch(Exception e){
			e.printStackTrace();
		}
	}
}

第一种方式创建的两个线程是完全独立的两个对象

所以它们各自有一个私有的 i ,并不受另外一个影响

而后两种方式,使用同一个Runnable实现类的对象或Callable实现类的对象创建的两个线程对象

它们是共享这个Runnable实现类的对象或Callable实现类的对象的

所以它们的 i 是互相会影响的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值