java多线程的两种创建方式

Thread 类构造方法的研究
Thread(Runnable target, AccessControlContext acc) {
        init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
    }

public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

public Thread(ThreadGroup group, Runnable target) {
        init(group, target, "Thread-" + nextThreadNum(), 0);
    }
public Thread(String name) {
        init(null, null, name, 0);
    }
public Thread(ThreadGroup group, String name) {
        init(group, null, name, 0);
    }



public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }



public Thread(ThreadGroup group, Runnable target, String name) {
        init(group, target, name, 0);
    }

public Thread(ThreadGroup group, Runnable target, String name,long stackSize) {
        init(group, target, name, stackSize);
    }

//Thread类的每个构造方法都调用了init方法,Thread共有8个构造方法
//而且所有的构造方法都依赖于init方法
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
        init(g, target, name, stackSize, null, true);
    }
Thread类的部分方法:


通过Thread的函数声明和方法我们知道Thread类是继承了一个叫Runnable的接口,并实现了这个接口的run方法
并且只能通过Thread类对象调用start()方法来启动一个新线程

从init的参数方法签名来看,构造一个Thread最多需要五个值,也就是说对于一个基本的Thread,能够运行的Thread,最大集合为五个;
但是通过构造方法可以看得出来,全部都是调用的四个版本的init方法,都没有传递AccessControlContext acc,在五个参数的版本中有设置默认值。
所以目前(1.8)支持Thread运行的构造参数最大集合个数为四,他们分别是:
ThreadGroup g
Runnable target
String name
long stackSize
最重要的是target参数,targer对象是实现了Runnable接口的类对象,这个参数指向的是你封装的任务在哪。
没有这个参数,就启动不了你指定的任务

任务的封装有多种,所以创建Thread类对象的时候指向你封装的任务就能启动对应的任务
Thread()空参构造方法和Thread(String name)创建的对象的target指向的是本对象的run()方法
Thread(含有Runnable target的参数)这样的构造方法重新定向了targer对象指定的任务,这样target指向
的任务就变成了实现Runnable的类的run()方法。


所以启动一个新的线程,要看targer的目标,targer指向的是这个新线程的任务(封装run方法的对象)
第一种方法是继承Thread类,创建本类对象来启动新线程。继承Thread类的子类的targer变量指向的是本类对象的run方法,
第二种方法是一个类实现Runnable接口来封装任务,利用Thread类的构造方法Thread(Runnable targer)来创建新的(Thread类对象)线程对象

因为Runnable接口有子接口,和具体的实现类所以也可以把Runnable的具体实现类传递给targer参数。
如FutureTask类,这个实现类有点特殊,因为他不仅实现了Runnable接口,而且还实现了一个叫Callable的接口
所以利用这个类,可以封装一种可抛异常可有返回值的任务。这个任务就封装在Call()方法中。所以这种方法的本质还是
属于第二种方法,因为传递给targer的参数还是实现了Runnable接口的类的对象

第一种方法

public class TheFristWay extends Thread {
    public  TheFristWay(){}
    public TheFristWay(String name){
        super(name);
    }
    public static void main(String[] args) {


        TheFristWay t = new TheFristWay("继承Thread的线程"); //继承Thread类来创建一个线程的时候,如果不重写构造方法,只能使用空参构造,因为Thread的构造方法不能被继承
        t.start();
        System.out.println("main is running ");

    }

    public void run(){    //run只是用来封装任务,具体的执行需要start调用
        System.out.println(Thread.currentThread().getName()+"  is running");
    }


}

第二种方法:1:

public class TheSecondWay {
    public static void main(String[] args) {
        //new Thread 是用来调用start方法的,new TheThread 是实现Runnable接口的对象
        new Thread(new TheThread(),"继承Runnable封装的线程").start();

        System.out.println("main is running ...");

    }

}

//这个类实现了Runnable并重新封装了run任务
class TheThread implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" is running...");
    }
}

第二种方法:2:

public class TheThiredWay {
    public static void main(String[] args) throws Exception {
        //Runnable接口的具体实现类(FutureTask对象),利用实现了Callable接口的对象来构造对象
        FutureTask<String> f = new FutureTask<>(new TheThred2());
        //Thread类对象利用Runnable具体实现类来启动新线程
        new Thread(f).start();
        //用FutureTask对象来获取返回值
        String s = f.get();
        System.out.println(s);


    }
}

class TheThred2 implements Callable{

    @Override
    public String call() throws Exception {

        System.out.println("这是call方法中封装的任务语句执行的结果");
        System.out.println(Thread.currentThread().getName());

        return "这是FutureTask对象通过get方法来获取的返回值"; //返回值,可以用FutureTask的get方法获取
    }
}

 

当使用 runnable 接口时,您不能直接创建所需类的对象并运行它;必须从 Thread 类的一个实例内部运行它。

实现Runnable接口创建线程比继承Thread类创建线程所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值