Thread、Runnable、Callable

2018-10-26  本文已影响0人  l老神仙l

1.Thread
/**

package thread;

public class Thread_Test extends Thread{

private int ticketnum = 10;
//重写run方法,run方法的方法体就是现场执行体
public void run() {
    for(int i=0; i<20;i++){
        if (this.ticketnum > 0) {
            ticketnum--;
            System.out.println("总共10张,卖掉1张,剩余" + ticketnum);
        }
    }
}
public static void main(String[] args)
{
    new Thread_Test().start();
    new Thread_Test().start();
    new Thread_Test().start();
    //实际上是卖掉了30张车票
}

}

输出:
总共10张,卖掉1张,剩余9
总共10张,卖掉1张,剩余8
总共10张,卖掉1张,剩余7
总共10张,卖掉1张,剩余6
总共10张,卖掉1张,剩余9
总共10张,卖掉1张,剩余8
总共10张,卖掉1张,剩余7
总共10张,卖掉1张,剩余6
总共10张,卖掉1张,剩余5
总共10张,卖掉1张,剩余5
总共10张,卖掉1张,剩余4
总共10张,卖掉1张,剩余9
总共10张,卖掉1张,剩余3
总共10张,卖掉1张,剩余2
总共10张,卖掉1张,剩余1
总共10张,卖掉1张,剩余0
总共10张,卖掉1张,剩余4
总共10张,卖掉1张,剩余3
总共10张,卖掉1张,剩余2
总共10张,卖掉1张,剩余1
总共10张,卖掉1张,剩余0
总共10张,卖掉1张,剩余8
总共10张,卖掉1张,剩余7
总共10张,卖掉1张,剩余6
总共10张,卖掉1张,剩余5
总共10张,卖掉1张,剩余4
总共10张,卖掉1张,剩余3
总共10张,卖掉1张,剩余2
总共10张,卖掉1张,剩余1
总共10张,卖掉1张,剩余0

2.Runnable
/**

package thread;

public class Runnable_Test implements Runnable {

private int ticketnum = 10;

public void run() {
    for(int i=0; i<20;i++){
        if (this.ticketnum > 0) {
            ticketnum--;
            System.out.println("总共10张,"+Thread.currentThread().getName()+"卖掉1张,剩余" + ticketnum);
        }
    }
}

public static void main(String[] args) {
    /*因为Runnable_Test是New了一次,使用的是同一个Runnable_Test,
    可以达到资源的共享。最终只卖出10张车票*/
    Runnable_Test rtt = new Runnable_Test();
    //使用三个线程调用
    new Thread(rtt, "卖票线程1").start();
    new Thread(rtt, "卖票线程2").start();
    new Thread(rtt, "卖票线程3").start();
}

}
输出:
总共10张,卖票线程1卖掉1张,剩余8
总共10张,卖票线程3卖掉1张,剩余7
总共10张,卖票线程2卖掉1张,剩余8
总共10张,卖票线程3卖掉1张,剩余5
总共10张,卖票线程1卖掉1张,剩余6
总共10张,卖票线程3卖掉1张,剩余3
总共10张,卖票线程2卖掉1张,剩余4
总共10张,卖票线程3卖掉1张,剩余1
总共10张,卖票线程1卖掉1张,剩余2
总共10张,卖票线程2卖掉1张,剩余0

3.Callable
/**

*/

package thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Callable_Test implements Callable<String> {
private int ticketnum = 10;

@Override
public String call() throws Exception {
    int t = 0;
    for (int i = 0; i < 20; i++) {
        if (this.ticketnum > 0) {
            ticketnum--;
            t++;
            System.out.println(Thread.currentThread().getName() + "总共10张,卖掉1张,剩余" + ticketnum);
        }
    }
    return t + "";
}

public static void main(String[] args) {
    Callable_Test ctt = new Callable_Test();
    FutureTask<String> ft1 = new FutureTask<>(ctt);
    FutureTask<String> ft2 = new FutureTask<>(ctt);
    FutureTask<String> ft3 = new FutureTask<>(ctt);
    Thread th1 = new Thread(ft1, "线程1");
    Thread th2 = new Thread(ft2, "线程2");
    Thread th3 = new Thread(ft3, "线程3");
    th1.start();
    th2.start();
    th3.start();

    try {
        System.out.println(th1.getName() + "的返回值:" + ft1.get());
        System.out.println(th2.getName() + "的返回值:" + ft2.get());
        System.out.println(th3.getName() + "的返回值:" + ft3.get());
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    }

}

}
输出:
线程2总共10张,卖掉1张,剩余7
线程2总共10张,卖掉1张,剩余6
线程2总共10张,卖掉1张,剩余5
线程2总共10张,卖掉1张,剩余4
线程2总共10张,卖掉1张,剩余3
线程2总共10张,卖掉1张,剩余2
线程1总共10张,卖掉1张,剩余7
线程3总共10张,卖掉1张,剩余7
线程1总共10张,卖掉1张,剩余0
线程2总共10张,卖掉1张,剩余1
线程1的返回值:2
线程2的返回值:7
线程3的返回值:1

创建线程的三种方式的对比:
采用实现Runnable、Callable接口的方式创见多线程时:
优势:
线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。
Callable有返回值
在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,
从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
劣势:
编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

使用继承Thread类的方式创建多线程时:
优势:
编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。
劣势:
线程类已经继承了Thread类,不能再继承其他父类。

上一篇 下一篇

猜你喜欢

热点阅读