Java 多线程(一) 线程的创建

来源:互联网 发布:制作毕业视频软件 编辑:程序博客网 时间:2024/04/26 14:41

JAVA虚拟机允许程序并发地执行多个线程,那如何去创建一个线程呢?

方法一:继承Thread类
1、将类声明为Thread的子类,该子类应重写Thread类的run()方法,将想要执行的代码写入run()方法,然后就可以分配并启动该子类的实例。
2、创建线程的子类对象,并调用该对象的start()方法。调用start()方法,Java虚拟机会默认调用该线程的run()方法。
     
方法二:
        创建线程的另一种方法是声明实现Runnable接口的类,该类实现run 方法。然后可以分配该类的实例,在创建Thread时作为一个参数来传递并启动。

示例:
方法一:
package com.mec.thread;public class TestExtendsThread extends Thread{@Overridepublic void run() {for(int i = 0; i < 100; i++){System.out.println("这是重写的run()方法!");}}}
package com.mec.thread;public class TestExtendsThreadDemo {public static void main(String[] args) {TestExtendsThread tet = new TestExtendsThread();tet.start();}}
运行结果:

方法二:
第一步:声明实现Runnable接口的类,该类实现run()方法
package com.mec.thread;public class AboutThread implements Runnable{@Overridepublic void run() {for(int i = 0; i < 1000000; i++){System.out.println("这是AboutThread implements Runnable类的run()方法的输出");}}}
第二步:测试类中创建线程,并以Runnable接口实现类的对象为参数
package com.mec.thread;public class AboutThreadTest extends Thread{public static void main(String[] args) {AboutThread at = new AboutThread(); //at是AboutThread类的对象,作为参数传递Thread thread = new Thread(at);thread.start();for(int i = 0; i < 100000; i++){System.out.println("--------主线程--------------------");}}}
运行结果:
                        
两种实现方法的区别是在源码层;
   方法一:子类重写了Thread类的run()方法,当调用start()方法时,直接调用子类的run()方法。
   方法二:这种方式将Runnable接口的实现类对象(即示例中 AboutThread类的对象at)作为参数传递给Thread类的构造方法,便于Thread类内部源码的使用,使得编译是看的是Runnable接口的run()方法,而执行的时候直接执行子类的run()方法。
   *下面我们来看具体的内部原理:
 1、这是在Thread类的内部: 首先、Runnable接口的对象作为参数传递给了Thread的构造函数,执行构造函数内部的init()方法。
    public Thread(Runnable target) {        init(null, target, "Thread-" + nextThreadNum(), 0);    }
2、我们再来看init()方法:
private void init(ThreadGroup g, Runnable target, String name,long stackSize){     .......     this.target = target;     .......}
3、它把传递进来的参数Rannable target赋值给了这个Thread类本身的Runnable target成员。接下来,也是最关键的地方是:
    @Override    public void run() {        if (target != null) {            target.run();        }    }
   Thread类的run()方法调用了target的run()方法,而target是Runnable接口的实现类对象,它的run方法实际就是Runnable接口的run()方法!所以,方法二创建线程在编译时实际执行的是Runnable接口的run(),运行时执行的是子类的run()。
证明:
package com.mec.thread;public class Test {public static void main(String[] args) {new Thread(new Demo1()){public void run(){System.out.println("执行");}}.start();}}class Demo1 implements Runnable{@Overridepublic void run() {System.out.println("Runnable");}}
输出结果:

输出很明显证明了运行时的run()是Thread对象的run()方法而不是Runnable接口的run()方法。



阅读全文
1 0
原创粉丝点击