Java創建線程的三種方式


進程和線程的區別

進程是重量級的任務,需要分配給它們獨立的地址空間。進程間通信是昂貴和受限的。進程間的轉換也是很需要花費的。

另一方面,線程是輕量級的選手。它們共享地址空間並且共享同一個進程。線程間通信是便宜的,線程間的轉換也是低成本的。

 

線程的生命周期

一個線程從創建到消亡的過程。線程的生命周期分為四個狀態

1、創建狀態

2、可運行狀態

3、不可運行狀態

4、消亡狀態

 

線程的狀態轉換圖

 

 

Java創建線程的三種方式: 1 繼承Thread, 2.實現Runnable接口   3、實現Callable接口

一、Java 使用線程方式Thread和Runnable,以及Thread與Runnable的區別

<一>. java中實現線程的方式有Thread和Runnable

Thread:

public class Thread1 extends Thread{
	@Override
	public void run() {
		System.out.println("extend thread");
	}
}

 Runnable:

public class ThreadRunable implements Runnable{

	public void run() {
		System.out.println("runbale interfance");
		
	}
	
}

 使用

public static void main(String[] args) {
		new Thread1().start();
		new Thread(new ThreadRunable()).start();
	}

  

 

<二>.Thread和Runnable區別

 1.在程序開發中使用多線程實現Runnable接口為主。 Runnable避免繼承的局限,一個類可以繼承多個接口

 2. 適合於資源的共享

   如下面的例子   

public class TicketThread extends Thread{
	
	private int ticketnum = 10;
	
	@Override
	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) {
		TicketThread tt1 = new TicketThread();
		TicketThread tt2 = new TicketThread();
		TicketThread tt3 = new TicketThread();
		tt1.start();
		tt2.start();
		tt3.start();
	}

  實際上是賣掉了30張車票

而使用Runnable,如下面的例子

public class TicketRunnableThread 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張,賣掉1張,剩余" + ticketnum);
			}
		}
	}
}

  使用三個線程調用

public static void main(String[] args) {
		TicketRunnableThread trt1 = new TicketRunnableThread();
		new Thread(trt1).start();
		new Thread(trt1).start();
		new Thread(trt1).start();
	}

  因為TicketRunnableThread是New了一次,使用的是同一個TicketRunnableThread,可以達到資源的共享。最終只賣出10張車票。

 

3.效率對比

public static void main(String[] args) {
	
		 long l1 = System.currentTimeMillis();

		    for(int i = 0;i<100000;i++){
		        Thread t = new Thread();
		    }

		    long l2 = System.currentTimeMillis();

		    for(int i = 0;i<100000;i++){
		        Runnable r = new Runnable() {
		            public void run() {
		            }
		        };
		    }

		    long l3 = System.currentTimeMillis();

		    System.out.println(l2 -l1);
		    System.out.println(l3 -l2);
	}

  在PC上的結果

119
5

  所以在使用Java線程池的時候,可以節約很多的創建時間

 

二、線程池

public class MyCallable implements Callable<Object> {

    private String taskNum;

    MyCallable(String taskNum){
        this.taskNum = taskNum;
    }

    @Override
    public Object call() throws Exception {
        System.out.println(">>>" + taskNum + "任務啟動");
        Date dateTmp1 = new Date();
        Thread.sleep(1000);
        Date dateTmp2 = new Date();
        long time = dateTmp2.getTime() - dateTmp1.getTime();
        System.out.println(">>>" + taskNum + "任務終止");
        return taskNum +"任務返回運行結果,當前任務執行時間[" + time + "]毫秒";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        int taskSize = 5;
        //創建一個線程池
        ExecutorService pool = Executors.newFixedThreadPool(taskSize);
        //創建多個有返回值的任務
        List<Future> list = new ArrayList<>();
        for(int i = 0; i< taskSize; i++){
            Callable c = new MyCallable(i+ " ");
            //執行任務並獲取Future對象
            Future f = pool.submit(c);
            list.add(f);
        }
        pool.shutdown();

        for(Future f : list){
            //從Future對象獲取任務的返回值
            System.out.println(">>>" + f.get().toString());
        }

    }
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM