java线程(1)——三种创建线程的方式

来源:互联网 发布:双十一淘宝多少钱 编辑:程序博客网 时间:2024/06/07 21:11

前言


线程,英文Thread。在java中,创建线程的方式有三种:

1、Thread

2、Runnable

3、Callable


在详细介绍下这几种方式之前,我们先来看下Thread类和Runnable接口。


Runnable接口

接口中只有一个run()方法,等待实现类去实现。

package java.lang;@FunctionalInterfacepublic interface Runnable {    public abstract void run();}



Thread类

该类实现了Runnable接口,也提供了很多其他的方法,如yield(),join()等

package java.lang;publicclass Thread implements Runnable {//获取当前线程public static native Thread currentThread();public static native void yield();//一系列的构造函数 public Thread(Runnable target, String name) {        init(null, target, name, 0);    } public Thread(ThreadGroup group, String name) {        init(group, null, name, 0);    }/*调用该方法时,jvm会调用run方法*Causes this thread to begin execution; the Java Virtual Machine    * calls the run method of this thread.*/public synchronized void start() {               if (threadStatus != 0)            throw new IllegalThreadStateException();        group.add(this);        boolean started = false;        try {            start0();            started = true;        } finally {            try {                if (!started) {                    group.threadStartFailed(this);                }            } catch (Throwable ignore) {                           }        }    }}


一、实现Runnable接口

public class i_Runnable {/** * 主线程main方法 * @param args */public static void main(String[] args) {for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + "====" + i);if (i == 20) {RunnableThreadTest rtt = new RunnableThreadTest();//子线程new Thread(rtt, "new Thread[1]====").start();//new Thread(rtt, "新线程2").start();}}}/** * RunnableThreadTest实现Runnable接口 * @author YANG * */static class RunnableThreadTest implements Runnable {private int i;@Overridepublic void run() {for (i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName() + " " + i);}}}}



执行结果:

   



注意: 

    ** 执行结果只截取了部分内容。

    ** 如果RunnableThreadTest类前不加static,会报错No enclosing instance of type i_Runnable is accessible. Must qualify the allocation with an enclosin。因为只有内部类修饰为静态时,才可以在静态类方法(main方法)中调用该类的成员变量和方法。



二、继承Thread类

public class a_Thread {public static void main(String[] args) {Runner1 r=new Runner1();r.start(); //已经有thread 不需要new,直接调用start即可。for (int i = 0; i < 100; i++) {System.out.println("main Thread:"+i);}}//Runner1继承Thread类,重写run方法static class Runner1 extends Thread{@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("Runner1:"+i);}}}}


思考:能不能将上面的r.start(); 改为 r.run();

分析:换成run()方法之后,就变成了普通的方法调用,只有一个主线程,没有子线程。

执行结果:为了方便显示,我们将循环次数改为10。


Runner1:0Runner1:1Runner1:2Runner1:3Runner1:4Runner1:5Runner1:6Runner1:7Runner1:8Runner1:9main Thread:0main Thread:1main Thread:2main Thread:3main Thread:4main Thread:5main Thread:6main Thread:7main Thread:8main Thread:9


三、实现Callable接口

       前面两种方式是传统的线程技术中的内容,第三种方式Callable和Future是jdk1.5之后新增的。我们先来补充点东西,看看这种方式与之前的方式有什么联系。

//实现Callable接口public class j_CallableTest implements Callable<String> {public static void main(String[] args) {j_CallableTest test=new j_CallableTest();FutureTask<String> ft=new FutureTask<>(test);for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+" i的值为="+i);if(i==20){new Thread(ft,"子线程").start();}}}//重写call方法@Overridepublic String call() throws Exception {int i = 0;String reString = "";for (; i < 100; i++) {reString = Thread.currentThread().getName() + " " + i;System.out.println(reString);}return reString;}}

      从上面可以看到,new Thread的方式还是用的public Thread(Runnable target, String name); 说明FutureTask也是Runnable类型的,他们之间的关系可以从下图中看出来。



那么,使用Callable和Future的方式有什么特点呢?

我们从他们的定义来看,Callable接口中只有一个方法,返回值为V。前两种方式都是返回void。

@FunctionalInterfacepublic interface Callable<V> {    /**     * Computes a result, or throws an exception if unable to do so.     *     * @return computed result     * @throws Exception if unable to compute a result     */    V call() throws Exception;}


小结:

       1、接口实现更灵活,java不支持多继承。在这方面,Runnable和Callable更有优势。

       2、返回值问题。Runnable和Thread都不能有返回值,但Callable可以,而且支持多种类型的数据。


       就这两点来看,新增的Callable和Future的实现方式优势十分明显啊。但是追到原理,其实这三种都可以归结为一种方式。


0 0