1. 程式人生 > >java多執行緒與併發之建立執行緒的幾種方式

java多執行緒與併發之建立執行緒的幾種方式

1、繼承Thread類方法

public class Demo1 extends Thread{

	@Override
	public void run() {
		//判斷標誌
		while(true) {
		     System.out.println(getName()+"-->執行緒執行了....");
		}
	}
	
	public static void main(String[] args) {
		Demo1 d1 = new Demo1();
		d1.start();
	}
	
}

2、實現Runnable介面

/**
 * Runnable 作為執行緒任務存在
 * @author abel
 */
public class Demo2 implements Runnable {
	@Override
	public void run() {
		while(true) {
			System.out.println("執行緒開始執行......");
		}
	}
	
	public static void main(String[] args) {
		Thread t = new Thread(new Demo2());
		
		t.start();
	}
}

3、採用匿名內部類的方式建立執行緒(使用一次的時候使用)

public class Demo3 {

    public static void main(String[] args) {
        //1)通過thread子類建立匿名內部類
        new Thread() {
            public void run() {
                System.out.println("執行緒開始執行......");
            };
        }.start();
        
        //2)通過執行緒任務的方式建立匿名內部類
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("執行緒開始執行......");
                
            }
        }).start();
    }
}
擴充套件:採用匿名內部類的方式同時採用上面兩種方式會執行子類的run方法
public class Demo3 {

	public static void main(String[] args) {
		new Thread(new Runnable() { 
			@Override
			public void run() {
				System.out.println("實現runnable介面的run方法......");
			}
		}) {
			public void run() {
				System.out.println("執行的子類的run方法......");
			};
		}.start();
	}
}
結果:
執行的子類的run方法......
原因:因為Thread類在new的時候,雖然傳了Runnable也就是原始碼中的target已經傳到init中了,並且在init中賦給了Thread類的target屬性(此時target指向的是引數中的runnable介面),之後在呼叫start()啟動的時候,就去呼叫了run()方法
public void run() {
    if (target != null) {
        target.run();
    }
}
但子類重寫了run(),所以最後執行的是子類的run()方法,而沒呼叫父類的run()。

4、有返回值的建立方式(實現Callable介面)

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

//引數使用泛型,以Integer為例
public class Demo4 implements Callable<Integer>{

	@Override
	public Integer call() throws Exception {
		System.out.println("正在執行方法體......");
		Thread.sleep(3000);
		return 100;
	}

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		Demo4 d = new Demo4();
		//FutureTask是繼承Runnable,是對Runnable的封裝,所以需要包裝到Thread類中執行
		FutureTask<Integer> task = new FutureTask<>(d);
		
		//包裝到Thread類中進行執行
		Thread t = new Thread(task);
		t.start();
		
		System.out.println("執行別的任務....");
		//獲取執行緒執行結果
		Integer i = task.get();
		System.out.println("執行緒執行結果是:"+i);
	}
}
執行結果:
執行別的任務....
正在執行方法體......
執行緒執行結果是:100

5、定時器的方式建立執行緒

public class Demo5 {
	public static void main(String[] args) {
		Timer timer = new Timer();
		//TimerTask是一個抽象類,實現的是runnable介面
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				System.out.println("執行執行緒任務......");
			}
		}, 0, 1000);
	}
}
有很多schedule可選

注意:方法體中出現異常後,該定時任務直接結束

6、使用執行緒池建立執行緒

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo6 {
    public static void main(String[] args) {
        //建立執行緒池,有多種可選執行緒池
        ExecutorService threadPool = Executors.newFixedThreadPool(10);
        for (int i = 0; i < 100; i++) {
            threadPool.execute(new Runnable() { //執行一次
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"-->執行緒執行......");
                    
                }
            });
        }
        //停掉當前執行緒池
        threadPool.shutdown();
    }
}


執行結果:
pool-1-thread-1-->執行緒執行......
pool-1-thread-5-->執行緒執行......
pool-1-thread-2-->執行緒執行......
pool-1-thread-3-->執行緒執行......
pool-1-thread-6-->執行緒執行......
pool-1-thread-4-->執行緒執行......
pool-1-thread-9-->執行緒執行......
pool-1-thread-7-->執行緒執行......
pool-1-thread-8-->執行緒執行......
pool-1-thread-10-->執行緒執行......

7、採用lambda表示式(函式式)實現

import java.util.Arrays;
import java.util.List;

public class Demo7 {
	public int add(List<Integer> values) {
//		values.parallelStream().forEach(System.out :: println);
		//parallelStream是個並行的
		return values.parallelStream().mapToInt(i -> i).sum();
	}
	public static void main(String[] args) {
		
		List<Integer> values = Arrays.asList(10,20,30,40);
		int sum = new Demo7().add(values);
		System.out.println("計算結果是:"+sum);
	}
}
執行結果:
30
40
10
20
計算結果是:100