注:主要記錄創建的步驟,代碼僅供參考
方式一:繼承Thread
/** * 創建多線程方式一:繼承Thread * 1:創建一個繼承於Thread類的子類 * 2:重寫Thread類的run() * 3:創建Thread類的子類對象 * 4:通過此對象調用start() */ public class ThreadTestOne { public static void main(String[] args) { MyThread myThread1 = new MyThread(); MyThread myThread2 = new MyThread(); myThread1.start(); myThread2.start(); for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } } } class MyThread extends Thread { @Override public void run() { for (int i = 1; i <= 100; i++) { if (i % 2 == 0) { System.out.println(Thread.currentThread().getName() + ":" + i); } } } }
方式二:實現Runnable接口
/** * 創建多線程的方式二:實現Runnable接口 * 1:創建一個實現了Runnable接口的類 * 2:實現類去實現Runnable中的抽象方法:run() * 3:創建實現類的對象 * 4:將此對象作為參數傳遞到Thread類的構造器中,創建Thread類的對象 * 5:通過Thread類的對象調用start() */ public class ThreadTestTwo { public static void main(String[] args) { MThread mThread = new MThread(); Thread thread = new Thread(mThread); thread.setName("進程一"); thread.start(); Thread thread2 = new Thread(mThread); thread2.setName("進程二"); thread2.start(); } } class MThread implements Runnable { @Override public void run() { for (int i = 0; i < 100; i++) { if (i % 2 == 0) { System.out.println(Thread.currentThread().getName() + ":" + i); } } } }
方式三:實現Callable接口
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; /** * 多線程創建方式之三:實現Callable接口。jdk5.0新增 * 1:創建一個實現Callable的實現類 * 2:實現call方法,將此線程需要執行的操作聲明在call方法中 * 3:創建Callable接口實現類的對象 * 4:將此Callable接口實現類的對象作為參數傳遞到FutureTask構造器中,創建FutureTask的對象 * 5:將FutureTask的對象作為參數傳遞到Thread類的構造器中,創建Thread對象並調用start() * 6:使用FutureTask的get方法獲取Callable中call方法的返回值(可不獲取) */ public class ThreadTestThree { public static void main(String[] args) throws ExecutionException, InterruptedException { ThirdThread thirdThread = new ThirdThread(); FutureTask futureTask = new FutureTask(thirdThread); Thread thread = new Thread(futureTask); thread.setName("線程一"); thread.start(); for (int i = 1; i <= 100; i++) { if (i % 2 != 0) { System.out.println(Thread.currentThread().getName() + ":" + i); } } Object o = futureTask.get(); System.out.println(Thread.currentThread().getName() + ": 線程一總和為" + o); } } class ThirdThread implements Callable { @Override public Object call() throws Exception { int sum = 0; for (int i = 1; i <= 100; i++) { if (i % 2 == 0) { System.out.println(Thread.currentThread().getName() + ":" + i); sum += i; } } return sum; } }
方式四:線程池
import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; /** * 創建多線程方式之四:線程池 * 1:提供線程池 * 2:執行指定的線程操作,需提供Runnable或Callable的實現類對象 * 3:關閉線程池 */ public class ThreadTestFour { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(10); //獲取接口的實現類型 //System.out.println(executorService.getClass()); ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService; //設置線程池的屬性 threadPoolExecutor.setCorePoolSize(12); threadPoolExecutor.setMaximumPoolSize(10); /** * executorService.execute(Runnable commd); * executorService.submit(Callable commd):可用FutureTask獲取結果; */ executorService.submit(new ThreadTest()); executorService.submit(new ThreadTest()); executorService.shutdown(); } } class ThreadTest implements Callable { @Override public Object call() throws Exception { int sum = 0; for (int i = 1; i <= 100; i++) { if (i % 2 == 0) { System.out.println(Thread.currentThread().getName() + ":" + i); sum += i; } } return sum; } }
例:三個窗口同時售票
public class ThreadRunnableLearn { public static void main(String[] args) { RunnableThread runnableThread = new RunnableThread(); Thread thread1 = new Thread(runnableThread); thread1.setName("窗口一"); Thread thread2 = new Thread(runnableThread); thread2.setName("窗口二"); Thread thread3 = new Thread(runnableThread); thread3.setName("窗口三"); thread1.start(); thread2.start(); thread3.start(); } } class RunnableThread implements Runnable { private int ticket = 100; @Override public void run() { while (true) { /** * 解決線程安全問題有三種方式: * 一:同步代碼塊(如例),RunnableThread類也是一個對象,而且只會加載一次,所以是唯一的 * 二:同步方法【private synchronized void 方法名() {}】當操作共享數據的代碼在一個方法中,則可使用 * 當同步方法為非靜態:則默認同步監視器是this * 當同步方法為靜態: 則默認同步監視器是該方法屬於的類 xxx.class * 三:ReentrantLock */ synchronized (RunnableThread.class) { if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "售票,票號為" + ticket); ticket--; }else { break; } } } } }