Java较深入的探讨总结1——多线程三种实现方式

在Java中,多线程的实现方法大致可以分为三类:

1.继承Thread类;子类继承Thread类具备多线程能力。有OOP单继承的局限性。
2.实现Runnable接口;实现接口Runnable具有多线程能力。避免单继承局限性,灵活方便,方便同一个对象被多个线程使用。
3.实现Callable接口

 继承Thread类实现多线程:利用这种方法实现多线程,需要的是继承Thread类并且重写run()方法,线程的运行就是执行run()方法的过程。
具体的实例如下:

class Mythread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i <3 ; i++) {
            try {
                Thread.sleep(1000);//休眠是有异常的,所以需要捕获
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread线程的第"+i+"次执行!");
        }
    }
}

 实现Runnable接口实现多线程:和Thread的继承类似,需要的是实现Runnable的接口,并且重写run()方法,线程的执行也是run()的运行过程。
具体的实例如下:

class Myrunnable implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Runnable线程的第"+i+"次执行!");
        }
    }
}

重写的方法是call()方法。并且Callable实现的多线程是有返回值的。
具体实例如下:

class Mycallable implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        for (int i = 0; i <3 ; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Callable线程的第"+i+"次执行!");
        }
        return 100;
    }
}

 对上面三种多线程的实现方式进行运行,跑起来,需要使用的方法都不一样,Thread是直接调用start()方法,而Runnable则是需要使用Thread代理,再调用start()方法。Callable需要的方法比较复杂,也不唯一,可以使用FutureTask类进行代理,然后使用Thread类的start()方法进行运行。
具体的代码如下:

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

public class threadtest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {//这里的异常来自futur.Task.get(),可以进行抛出。

        new Mythread().start();//方法1

        new Thread( new Myrunnable(),"Runnable").start();//方法2

        FutureTask<Integer> futureTask= new FutureTask<Integer>(new Mycallable());//方法3
        new Thread(futureTask,"Callable").start();
        System.out.println(futureTask.get());//用来获取线程的返回值
    }
}

执行结果如下:

Runnable线程的第0次执行!
Thread线程的第0次执行!
Callable线程的第0次执行!
Thread线程的第1次执行!
Runnable线程的第1次执行!
Callable线程的第1次执行!
Runnable线程的第2次执行!
Thread线程的第2次执行!
Callable线程的第2次执行!
100

 观察可以发现,虽然都是执行了三次,但是对于执行的顺序却不一样,可以表明这三个线程是同时在运行的,而不是按照某个特定的顺序运行。