1. Thread java
2. Runnable 多線程
3. Callable ide
Runnable/Thread 區別 this
1. Java 不支持多繼承, 因此實現接口Runnable是一個比較好的選擇. atom
2. 從設計的角度看,實現子類一般意味着添加或者修改一些功能, 而實現接口則表示實現一個統一的動做.因此通常狀況實現Runnable較好. spa
3. Runnable接口表明了一個Task, 能夠被Thread/Executors來調用, 從這點來講將一個Task做爲Runnable來實現比較好. 線程
因此若是在Runnable和Thread中取捨, 仍是選擇Runnable吧.若是應用ExecutorService不要忘記shutdown. 設計
package thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import java.util.concurrent.atomic.AtomicInteger; public class ThreadTest { public static void main(String args[]) throws Exception{ MyThread mt = new MyThread(); //mt.run(); If we call run like this, the thread is main thread mt.start(); MyRunnable mr = new MyRunnable(); //mr.run();If we call run like this, the thread is main thread Thread t = new Thread(mr); t.start(); MyExecutors.executeThreads(); } } class MyThread extends Thread { public void run(){ System.out.println("This is MyThread "); System.out.println("In MyThread Current Thread " + Thread.currentThread().getId()); } } class MyRunnable implements Runnable { @Override public void run() { System.out.println("This is Runnable"); System.out.println("In Runnable Current Thread " + Thread.currentThread().getId()); } } class MyExecutors { public static void executeThreads() throws Exception { ExecutorService executorService = Executors.newFixedThreadPool(2); FutureTask<String> fts = new FutureTask<String>(new Callable<String>() { @Override public String call() throws Exception { System.out.println("Callable"); return "Current threadid is " + Thread.currentThread().getId(); } }); executorService.submit(fts); executorService.shutdown(); ExecutorService es = Executors.newFixedThreadPool(2); List<Future<String>> futures = new ArrayList<Future<String>>(); for (int i = 0; i < 5; i++) { futures.add(es.submit(new Task())); } for (Future<String> future : futures) { try { System.out.println(future.get()); } catch (ExecutionException ee) { System.err.println(ee.getCause()); } } es.shutdown(); } static class Task implements Callable<String> { private static AtomicInteger i = new AtomicInteger(1); public String call() throws Exception { i.incrementAndGet(); if (i.get() % 2 != 0) { throw new RuntimeException("That's odd, I failed."); } return "I'm done"; } } }
線程間的同步方法大致可分爲兩類:用戶模式和內核模式。顧名思義,內核模式就是指利用系統內核對象的單一性來進行同步,使用時須要切換內核態與用戶態,而用戶模式就是不須要切換到內核態,只在用戶態完成操做。
用戶模式下的方法有:原子操做(例如一個單一的全局變量),臨界區。內核模式下的方法有:事件,信號量,互斥量。
code
多線程同步和互斥有何異同 對象
線程同步是指線程之間所具備的一種制約關係,一個線程的執行依賴另外一個線程的消息,當它沒有獲得另外一個線程的消息時應等待,直到消息到達時才被喚醒。
線程互斥是指對於共享的進程系統資源,在各單個線程訪問時的排它性。當有若干個線程都要使用某一共享資源時,任什麼時候刻最多隻容許一個線程去使用,其它要使用該資源的線程必須等待,直到佔用資源者釋放該資源。線程互斥能夠當作是一種特殊的線程同步