创建线程的三种方式

线程的创建

创建线程具体来说有三种方式,详细内容如下文.

继承Thread类

详细步骤:

1.定义Thread类的子类,并重写该类的run()方法,run()方法被称为线程执行体.

2.创建Thread子类的实例,即创建线程对象.

3.调用线程对象的start()方法启动该线程.

代码示例:

/**
 * Created by dongmengyuan on 18-2-21.
 */

public class FirstThread extends Thread {
    //i是FirstThread的实例属性,不是局部变量
    private int i;
    //重写run()方法,run()方法的方法体是线程执行体
    public void run() {
        for( ; i < 100; i++) {
            //当线程使用继承Thread类时,直接使用this就可以获取当前线程
            //Thread对象的getName()返回当前线程的名字
            //直接调用getName()方法返回当前线程的名字
            System.out.println(getName() + " " + i);
        }
    }

    public static void main(String[] args) {
        for(int i = 0; i < 100; i++) {
            //调用Thread的currentThread()方法获取当前线程
            System.out.println(Thread.currentThread().getName() + " " + i);
            if(i == 20) {
                //创建并启动第一个线程
                new FirstThread().start();
                //创建并启动第二个线程
                new FirstThread().start();
            }
        }

    }
}

上面程序显式的创建了两个线程,但是实际上程序有三个线程,其中包括主线程.

当Java程序开始运行时,程序至少会创建一个主线程,主线程的执行体不是由run()方法确定的,而是由main()方法确定的.

*使用继承Thread类的方法创建线程时,多个线程之间无法共享线程类的实例变量.

实现Runnable接口

详细步骤:

1.定义Runnable接口的实现类,并重写该接口的run()方法.

2.创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象.

3.调用线程对象的start()方法来启动该线程.

代码示例:

/**
 * Created by dongmengyuan on 18-2-21.
 */

public class SecondThread implements Runnable {
    private int i;

    public void run() {
        //当线程类实现Runnable接口时,如果想要获取当前线程,只能用Thread.currentThread()方法
        System.out.println(Thread.currentThread() + " " + i);
    }

    public static void main(String[] args) {
        for(int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
            if(i == 20) {
                SecondThread st = new SecondThread();
                //通过new Thread(target,name)方法创建新线程
                new Thread(st, "新线程1").start();
                new Thread(st, "新线程2").start();
            }
        }

    }
}

*采用Runnable接口的方式创建的多个线程可以共享线程类的实例属性.因为这种方式下,程序所创建的Runnable对象只是线程的target,多个线程可以共享同一个target.

使用Callable和Future

详细步骤:

1.创建Callable接口的实现类,并实现call()方法,该call()方法作为线程执行体,且该call()方法有返回值.

2.创建Callable实现类的实例,使用Future Task类来包装Callable对象,该Future Task对象封装了Callable对象的call()方法的返回值.

3.使用Future Task对象作为Thread对象的target创建并启动新线程.

4.调用Future Task对象的get()方法来获得子线程执行结束后的返回值.

代码示例:

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * Created by dongmengyuan on 18-2-22.
 */

public class ThirdThread implements Callable<Integer> {
    //实现call()方法,作为线程执行体
    //call()方法可以有返回值
    public Integer call() {
        int i = 0;
        for(; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " 的循环变量i的值: " + i);
        }
        return i;
    }

    public static void main(String[] args) {
        //创建Callable对象
        ThirdThread rt  = new ThirdThread();
        //使用Future Task对象来包括Callable对象
        FutureTask<Integer> task = new FutureTask<Integer>(rt);
        for(int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName() + " 的循环变量i的值: " + i);
            if(i == 20) {
                //实质还是以Callable对象来创建并启动线程
                new Thread(task,"有返回值的线程").start();
            }
        }
        try {
            //获取线程返回值
            System.out.println("子线程的返回值:" + task.get());
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

*call()方法比run()方法功能更强大.  ---call()方法可以有返回值,可以声明抛出异常.

*Callable接口有泛型限制,Callable接口里的泛型形参类型与call()方法返回值类型相同.

创建线程的三种方式对比

实现Runnable接口和实现Callable接口的方式基本相同,只是Callable接口里定义的方法有返回值,可以声明抛出异常,大体上可以归结为一大类,这种方式与继承Thread方式之间的主要差别是:

    采用实现Runnable,Callable接口创建多线程

   1.线程类只是实现了Runnable接口或Callable接口,还可以继承其他类

            2.多个线程可以共享同一个target对象,非常适合多个相同线程来处理同一份资源的情况.(面向对象)

            3.如果要访问当前线程,必须使用Thread.currentThread()方法,比较复杂

    采用继承Thread类的方式创建多线程

            1.因为线程类已经继承了Thread类,所以不能再继承其他父类

            2.如果要访问当前线程,直接使用this即可获得

鉴于上述分析,通常推荐使用实现接口的方式来创建多线程,实现接口的方式比继承类的方式更灵活,也能减少程序之间的耦合度,面向接口编程也是设计模式6大原则的核心.






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值