java多线程系列(一):Thread、Runnable、Callable实现多线程的区别

实现多线程

java实现多线程的方法有三种,分别是继承thread类,实现runnable接口,实现callable接口(call方法有返回值)

/**
 * 继承Thread
 */
public class MyThread extends Thread{
     int a = 0;
    @Override
    public void run() {
        //线程的核心实现
        synchronized (this){
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println( ++a );
        }

    }
}

class MyThreadTest{
    public static void main(String[] args) {
        //实例三个线程
        MyThread myThread1 = new MyThread();
        MyThread myThread2 = new MyThread();
        MyThread myThread3 = new MyThread();

        //启动三个线程
        myThread1.start();
        myThread2.start();
        myThread3.start();
        
    }
}

输出结果:

/**
 * 实现Runnable接口
 */
public class MyRunnable implements Runnable {
    int a = 0;

    @Override
    public void run() {
        //线程核心处理方法
        System.out.println(++a);
    }

}

class MyRunnableTest {
    public static void main(String[] args) {
        //实例话MyRunnable
        Runnable runnable = new MyRunnable();

        //通过runnable实例化三个线程
        Thread thread1 = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        Thread thread3 = new Thread(runnable);

        //启动三个线程
        thread1.start();
        thread2.start();
        thread3.start();

        // 输出的结果为1  2  3  ,输出的顺序可能不同

    }
}

输出结果:

/**
 *
 * 实现Callable接口
 */
public class MyCallable implements Callable<String> {

    int a = 0;

    @Override
    public String call() throws Exception {
        ++a;
        System.out.println(Thread.currentThread().getName() + ",a=" + a);
        return String.valueOf(a);
    }
}

class TestCallable {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        Callable callable = new MyCallable();
        FutureTask<String> task = new FutureTask<String>(callable);


        Thread thread1 = new Thread(task,"线程一");
        Thread thread2 = new Thread(task,"线程二");
        Thread thread3 = new Thread(task,"线程三");

        thread1.start();
        thread2.start();
        thread3.start();
        // 取得返回值
        System.out.println(task.get());
        
    }
}

输出结果:




Thread、Runnable、Callable接口实现多线程的区别

观察以上三种实现方式和输出的结果可得
1.继承Thread方式,每次new Thread都是独立的,资源不共享,而Runnable资源共享;
2.实现Callable接口方式,只能运行一次FutureTask

Thread类与Runnable接口实现多线程的区别

1.Thread类是Runnable接口的子类,使用runnable接口实现多线程可以避免单继承局限;

2.Runnable接口实现的多线程可以比Thread类实现的多线程更加清楚的描述数据共享的概念。

如何理解:
因为一个线程只能启动一次,通过Thread实现线程时,线程和线程所要执行的任务是捆绑在一起的。也就使得一个任务只能启动一个线程,不同的线程执行的任务是不相同的,所以没有必要,也不能让两个线程共享彼此任务中的资源。

通过Runnable方式实现的线程,实际是开辟一个线程,将任务传递进去,由此线程执行。可以实例化多个 Thread对象,将同一任务传递进去,也就是一个任务可以启动多个线程来执行它。这些线程执行的是同一个任务,所以他们的资源是共享。

Calleble接口

1.最大的特点就是可以通过FutureTask获得线程核心处理方法的返回值(run方法是无返回值的
2.get方法会阻塞主线程来等待任务完成。FutureTask非常适合用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果

  1. FutureTask被多次调用,依然只会执行一次Runnable任务

猜你喜欢

转载自www.cnblogs.com/qiutianyou/p/10056465.html