一、繼承Thread類,複寫run方法,run方法中爲線程須要執行的邏輯部分,而啓動線程調用start方法。小示例見代碼,經過Thread.currentThread().getName()能夠得到當前線程名稱java
public class MyThread extends Thread { private int i; public void run(){ for(;i<100;i++){ System.out.println(Thread.currentThread().getName()+" "+i); } } }; public static void main(String[] args) { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+""+i); if(i==20){ new MyThread().start(); new MyThread().start(); } } }
二、因爲java不支持多繼承,當須要繼承另外一個類時,與第一種方式衝突。因而能夠使用第二種方法,經過實現Runnable接口。複寫run方法。代碼下緩存
public class MyThread2 implements Runnable{ private int i; @Override public void run() { for(;i<100;i++){ System.out.println(Thread.currentThread().getName()+" "+i); } } } public static void main(String[] args) { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+""+i); if(i==20){ MyThread2 myThread2 = new MyThread2(); new Thread(myThread2).start(); new Thread(myThread2).start(); } }
3使用callable和future,Callable()與Runable()不一樣的地方主要是,Callable方法有返回值。代碼以下併發
public class CallableDemo implements Callable<Integer> { @Override public Integer call() throws Exception { int i = 5; for(;i<100;i++){ System.out.println(Thread.currentThread().getName()+" "+i); } return i; } } public static void main(String[] args) { CallableDemo callableDemo = new CallableDemo(); FutureTask<Integer> futureTask = new FutureTask<Integer>(callableDemo); for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+""+i); if(i==20){ new Thread(futureTask,"有返回的線程:").start(); try { System.out.println("子線程的返回值" + futureTask.get()); }catch(Exception e){ e.printStackTrace(); } } } }
四、經過線程池建立線程,首先介紹幾個相關的類:Executor,Executors,ExecutorService,Future。Executor爲Java1.5後引入的一系列併發庫中與executor相關的功能類。
Executors爲一個建立線程的工廠,其中提供了4種建立線程的方式。
ide
<一> 建立固定數量的線程。其中參數即爲固定線程的數量。 線程
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
<二> 建立可緩存的線程,線程超過60s會被回收。當緩存的沒有線程能夠使用時,則建立新線程使用。該狀況下線程是無界的,只要想使用線程會無限的建立,除非發生內存溢出。 code
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
<三> 建立一個單線程化的Executor。 blog
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
<四> 建立一個支持定時及週期性的任務執行的線程池,多數狀況下可用來替代Timer類。 繼承
public static ScheduledExecutorService newScheduledThreadPool( int corePoolSize, ThreadFactory threadFactory) { return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory); }