Java创建线程的三种方式 - 每天五分钟搞定Java面试

继承Thread

(1)定义Thread类的子类,重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。
(2)创建Thread子类的实例,即创建了线程对象。
(3)调用线程对象的start()方法来启动该线程。

class thread extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
public class ThreadTest1 {
    public static void main(String[] args){
        System.out.println(Thread.currentThread().getName());
        for(int i = 0;i<5;i++){
            new thread().start();
        }
    }
}

实现Runnable接口

(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体是该线程的线程执行体。
(2)创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
(3)调用线程对象的start()方法来启动该线程。

class ThreadRunnable implements Runnable {
    @Override
    public void run() {
        //System.out.println(Thread.currentThread().getName());
        //这里直接使用this,指向当前线程, 这也是通过继承Thread类创建线程的好处,不需要使用Thread.currentThread()来获取当前线程
        System.out.println(this.getName());
    }
}
public class ThreadTest3 {
    public static void main(String[] args){
        System.out.println(Thread.currentThread().getName());
        for(int i = 0;i<5;i++){
            ThreadRunnable threadRunnable = new ThreadRunnable();
            new Thread(threadRunnable).start();
        }
    }
}

也可以使用匿名内部类的方式

public class ThreadTest2 {
    public static void main(String[] args){
        System.out.println(Thread.currentThread().getName());
        for(int i = 0;i<5;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            }).start();
        }
    }
}

使用Callable和FutureTask

(1)创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
(2)创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
(3)使用FutureTask对象作为Thread对象的target创建并启动新线程。
(4)调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

class CallableThread implements Callable<Integer>{
    private Integer score;

    public CallableThread(int score){
        this.score = score;
    }
    @Override
    public Integer call() throws Exception {
        return score;
    }
}
public class ThreadTest4 {
    public static void main(String[] args){
        System.out.println(Thread.currentThread().getName());
        CallableThread callableThread = new CallableThread(100);
        FutureTask<Integer> ft = new FutureTask<Integer>(callableThread);
        new Thread(ft,"with back result").start();
        try {
            System.out.println(ft.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

其实这个方法严格意义上不能说是创建了线程的方式,因为真正创建还是通过new Thread()来实现的。

比较

接口可以实现多继承,所以当实现Runnable或者是Callable接口的方式创建线程时,还可以实现其他接口或者继承其他的类。同时,这种方式,多个线程多个线程可以共享同一个target对象,非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
如果是通过继承Thread类来创建线程,则不可以再继承其他类。

猜你喜欢

转载自blog.csdn.net/SMonkeyKing/article/details/82625696