創建多線程的四種方式


注:主要記錄創建的步驟,代碼僅供參考

方式一:繼承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;
                }
            }
        }
    }
}

 

 
         
         
       


免責聲明!

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



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