天天看點

Java多線程(一)實作多線程Java多線程(一)實作多線程

Java多線程(一)實作多線程

在Java中,可以用Thread、Runnable以及Callable實作多線程

Thread 實作多線程

用Thread方法那麼就是目标類繼承(extends)Thread類,然後重寫父類的run函數,在執行多線程程式時,使用start函數執行。

class sellTicket extends Thread{
    private int tickets = 20;
    
    @Override
    public void run() {
        try {
            this.sell();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void sell() throws InterruptedException {
        while(tickets>0)
        {
            System.out.println("賣了一張票,現在還有"+--this.tickets);
            Thread.sleep(100);
        }
    }
}


public class testThread {

    public static void main(String[] args) throws InterruptedException {
        sellTicket st = new sellTicket();
        st.start();
        int index = 0;
        while(true) {
            System.out.println("--------------");
            Thread.sleep(100);
            if(index++>30)
                break;
        }
        }
}

           

如果不使用多線程,那麼看main函數的話,肯定是先賣票(輸出賣票資訊),再輸出----------,但是使用了多線程以後,就是主線程main函數以及sellTicket 線程一起運作,得到了如下的結果。

Java多線程(一)實作多線程Java多線程(一)實作多線程

Runnable 實作多線程

用Runnale實作多線程的方法與Thread是類似的,不同的是這個是implements Runnale,在執行多線程時是new一個Thread對象,并将Runnale的對象放入Thread對象中,再進行start()。

class sellTicket implements Runnable{
    private int tickets = 20;

    @Override
    public void run() {
        try {
            this.sell();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void sell() throws InterruptedException {
        while(tickets>0)
        {
            System.out.println("賣了一張票,現在還有"+--this.tickets);
            Thread.sleep(100);
        }
    }
}

public class testThread {
    public static void main(String[] args) throws InterruptedException {
        sellTicket st = new sellTicket();
        new Thread(st).start();
        int index = 0;
        while(true) {
            System.out.println("--------------");
            Thread.sleep(100);
            if(index++>30)
                break;
        }
	}
}

           

結果與上一個方法相同

Callable實作多線程

Callable實作多線程和上面兩種的差別在于Callable多線程操作後可以有傳回值,其次,用Callable實作的類的多線程操作寫在call()函數中,具體可以看下面代碼:

class TestCall implements Callable<String>
{
    @Override
    public String call() throws Exception {
        for (int i=0;i<10;i++)
        {
            System.out.println(Thread.currentThread().getName()+"   "+i);
        }
        return Thread.currentThread().getName() + "完成線程操作";
    }
}

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

        TestCall t1 = new TestCall();
        TestCall t2 = new TestCall();
        TestCall t3 = new TestCall();
        //建立執行服務
        ExecutorService service = Executors.newFixedThreadPool(3);
        //送出執行
        Future<String> r1 = service.submit(t1);
        Future<String> r2 = service.submit(t2);
        Future<String> r3 = service.submit(t3);

        //擷取結果
        String rs1 = r1.get();
        System.out.println(rs1);
        String rs2 = r2.get();
        System.out.println(rs2);
        String rs3 = r3.get();
        System.out.println(rs3);

        //關閉服務
        service.shutdownNow();
        }
}
           

結果如下圖所示

Java多線程(一)實作多線程Java多線程(一)實作多線程

Thread 與 Runnable 的差別和聯系

  1. Runnable的實作方式是實作其接口
  2. Thread的實作方式是繼承其類
  3. Thread實作了Runnable接口并進行了擴充,而Thread和Runnable的實質是實作的關系,不是同類東西,是以Runnable或Thread本身沒有可比性。

初學者會有這樣一個錯覺:Runnable更容易可以實作多個線程間的資源共享,而Thread卻不行,但實際上卻不是這樣的。

這是一段由Runnable方式寫成的多線程代碼

class sellTicket implements Runnable{

    static int tickets = 20;
    static Object o = new Object();

    @Override
    public void run() {
        try {
            this.sell();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void sell() throws InterruptedException {
            while (tickets > 0) {
                synchronized (o) {
                    if(tickets<=0)
                        break;
                    System.out.println(Thread.currentThread().getName() + "賣了一張票,現在還有" + --this.tickets);
                    Thread.sleep(100);
                }
            }

    }
}


public class testThread {


    public static void main(String[] args) throws InterruptedException, ExecutionException {
        sellTicket st1 = new sellTicket();
        sellTicket st2 = new sellTicket();
        sellTicket st3 = new sellTicket();
        new Thread(st1,"1").start();
        new Thread(st2,"2").start();
        new Thread(st3,"3").start();
        }
}
           
Java多線程(一)實作多線程Java多線程(一)實作多線程

然後将上段代碼改成Thread方式的如下

public class testThread {


    public static void main(String[] args) throws InterruptedException, ExecutionException {
        sellTicket st1 = new sellTicket();
        sellTicket st2 = new sellTicket();
        sellTicket st3 = new sellTicket();
        st1.start();
        st2.start();
        st3.start();
        }
}
class sellTicket extends Thread{

    static int tickets = 20;
    static Object o = new Object();


    @Override
    public void run() {
        try {
            this.sell();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void sell() throws InterruptedException {

            while (tickets > 0) {
                synchronized (o) {
                    if(tickets<=0)
                        break;
                    System.out.println(Thread.currentThread().getName() + "賣了一張票,現在還有" + --this.tickets);
                    Thread.sleep(100);
                }
            }
    }
}
           
Java多線程(一)實作多線程Java多線程(一)實作多線程

由此看無論哪種方式都可以實作多個線程之間的資源共享,隻需要做好同步或者鎖的操作即可。