Java多线程

来源:互联网 发布:淘宝铁观音怎么选 编辑:程序博客网 时间:2024/06/08 05:32

Java语言中多线程的实现有3种方法

1.继承Thread类,重写run()

public class Test1 extends Thread{    @Override    public void run(){        System.out.println("thread begin!");    }    public static void main(String[] args){        Test1 test = new Test1();        test.start();    }}

该线程实例的创建依赖于Thread类,那么看下源码Thread类的实现:

public class Thread implements Runnable{            //  ......        //先将新建的线程添加进线程组中,标志为可运行状态        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) {            }        }    }   @Override    public void run() {        if (target != null) {            target.run();        }    }}

需要注意的是:调用start()后并不是立即执行多线程,而且Thread本质是实现Runnable接口的一个实例而已

我们通过调用Thread类的start()方法来启动一个线程,
这时此线程是处于就绪状态,
并没有运行。
然后通过此Thread类调用方法run()来完成其运行操作的,
这里方法run()称为线程体,
它包含了要执行的这个线程的内容,
Run方法运行结束,
此线程终止,
而CPU再运行其它线程。

2.实现Runnable接口,实现接口中的run()

主要步骤:

自定义类并实现Runnable接口,实现run()
创建Thread对象,用实现Runnable接口的对象作为参数实例化该Thread对象
调用Thread的start()

public class Test2 implements Runnable{    @Override    public void run(){        System.out.println("thread begin!");    }    public static void main(String[] args){        Test2 test = new Test2();        test.run();    }}

Runnable接口的源码:

public interface Runnable {    public abstract void run();}

通过两个demo我们发现,其实不管是继承Thread类还是实现Runnable接口来实现多线程,最终都是通过Thread对象的API控制线程

不过,我们也发现run()方法和start()方法似乎有着相似的功能,但又不一样。
试着比较下他们的区别

class ThreadDemo extends Thread{    @Override    public void run(){        System.out.println("ThreadDmo:begin!");        try {            Thread.sleep(1000);        } catch (Exception e) {            // TODO: handle exception            e.printStackTrace();        }finally{            System.out.println("ThreadDemo:end!");        }    }}public class Test3 {    public static void test1(){        System.out.println("test1:begin!");        Thread t1 = new ThreadDemo();        t1.start();        System.out.println("test1:end!");    }    public static void test2(){        System.out.println("test2:begin!");        Thread t2 = new ThreadDemo();        t2.run();        System.out.println("test2:end");    }    public static void main(String[] args){        test1();        try {            Thread.sleep(5000);        } catch (Exception e) {            // TODO: handle exception            e.printStackTrace();        }finally{            System.out.println();            test2();        }    }}

输出:

test1:begin!
test1:end!
ThreadDmo:begin!
ThreadDemo:end!

test2:begin!
ThreadDmo:begin!
ThreadDemo:end!
test2:end

从test1的运行结果可以看出,线程t1是从test1方法结束后才执行的System.out.println(“test1:end”)语句不需要等待t1.start()运行结果就可以执行
test1中调用start()方法是异步的。所以main()线程与t1线程是异步的。从test2的运行结果可以看出,调用t1.run()是同步的调用方法,因为System。out.println(“test2:end”)。只有等t1.run()调用结束后才可执行