★18.同時

7672 ワード

スレッドクラスの定義


方法一:Runnable


1.Runnableインタフェースの実装

public class Liftoff implements Runnable {
    private int countDown = 10;
    private static int taskCount = 0;
    private final int id = taskCount++;

    private String status() {
        return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff!") + "), ";
    }

    public void run() {
        while (countDown-- > 0) {
            System.out.print(status());
            Thread.yield();
        }
    }
}

2.Threadクラスの使用

public class BasicThreads {
    public static void main(String[] args) {
        Thread t1 = new Thread(new LiftOff());
        t1.start();
        Thread t2 = new Thread(new LiftOff());
        t2.start();
        System.out.println("Waiting for LiftOff");
    }
}

方式二:Thread

  • 欠点:Threadを継承すると他のクラスを継承できなくなり、Runnableインタフェースを実現する方法は他のクラス

    コード#コード#

  • を継承することもできる.
    public class SimpleThread extends Thread {
        private int countDown = 5;
        private static int threadCount = 0;
    
        private SimpleThread() {
            super(Integer.toString(++threadCount));
            start();
        }
    
        public String toString() { return "#" + getName() + "(" + countDown + "), "; }
    
        public void run() {
            while (true) {
                System.out.print(this);
                if (--countDown == 9) return;
            }
        }
    
        public static void main(String[] args) {
            for (int i = 0; i < 5; i++) {
                new SimpleThread();
            }
        }
    }
    

    方式3:Executors


    無限スレッドのスレッドプールの作成

    public class CachedThreadPool {
        public static void main(String[] args) {
            ExecutorService exec = Executors.newCachedThreadPool();
            for (int i = 0; i < 5; i++)
                exec.execute(new LiftOff());
            exec.shutdown();
        }
    }
    

    限られたスレッドのスレッドプールの作成

    public class FixedThreadPool {
        public static void main(String[] args) {
            ExecutorService exec = Executors.newFixedThreadPool(5);
            for (int i = 0; i < 5; i++)
                exec.execute(new LiftOff());
            exec.shutdown();
        }
    }
    

    単一スレッドの作成

    public class SingleThreadExecutor {
        public static void main(String[] args) {
            ExecutorService exec = Executors.newSingleThreadExecutor();
            for (int i = 0; i < 5; i++)
                exec.execute(new LiftOff());
            exec.shutdown();
        }
    }
    

    方式3:Callable

  • Runnableインタフェースと比較して、Callableインタフェースは、Futureオブジェクトパッケージ
  • を介してスレッドから値を返すことができる.
    class TaskWithResult implements Callable {
        private int id;
        TaskWithResult(int id) { this.id = id; }
        public String call() { return "result of TaskWithResult " + id; }
    }
    
    public class CallableDemo {
        public static void main(String[] args) {
            ExecutorService exec = Executors.newCachedThreadPool();
            ArrayList> results = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                results.add(exec.submit(new TaskWithResult(i)));
            }
            for (Future fs : results) {
                try {
                    // get 
                    System.out.println(fs.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    return;
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } finally {
                    exec.shutdown();
                }
            }
        }
    }
    

    休眠


    方式一

    Thread.sleep(100);
    

    方式2

    TimeUnit.MILLISECONDS.sleep(100);
    

    スレッド優先度

    public class SimplePriorities implements Runnable {
        private int countDown = 5;
        private int priority;
    
        private SimplePriorities(int priority) {
            this.priority = priority;
        }
    
        public void run() {
            //  
            Thread.currentThread().setPriority(priority);
            while (true) {
                for (int i = 1; i < 100000; i++) {
                    if (i % 1000 == 0) {
                        Thread.yield();
                    }
                }
                if (--countDown == 0) {
                    return;
                }
            }
        }
    
        public static void main(String[] args) {
            ExecutorService exec = Executors.newCachedThreadPool();
            for (int i = 0; i < 5; i++) {
                exec.execute(new SimplePriorities(Thread.MIN_PRIORITY));
            }
            exec.execute(new SimplePriorities(Thread.MAX_PRIORITY));
            exec.shutdown();
        }
    }
    

    バックグラウンドスレッド


    説明

  • プログラムのすべての非バックグラウンドスレッドが中止されると、バックグラウンドスレッドは殺されます.
  • 通常、バックグラウンドスレッドプログラムには不可欠または不可欠な部分ではありません.
  • バックグラウンドスレッドで作成されたスレッドもバックグラウンドスレッドです.

  • 単純な例

    public class SimpleDaemons implements Runnable {
        public void run() {
            try {
                while (true) {
                    TimeUnit.MILLISECONDS.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] arms) throws Exception {
            for (int i = 0; i < 10; i++) {
                Thread daemon = new Thread(new SimpleDaemons());
                //  
                daemon.setDaemon(true);
                daemon.start();
            }
            TimeUnit.MILLISECONDS.sleep(175);
        }
    }
    

    ThreadFactory

    //  ThreadFactory 
    class DaemonThreadFactory implements ThreadFactory {
        public Thread newThread(@NotNull Runnable r) {
            Thread t = new Thread(r);
            t.setDaemon(true);
            return t;
        }
    }
    
    public class DaemonThread implements Runnable {
        public void run() {
            try {
                while (true) {
                    TimeUnit.MILLISECONDS.sleep(100);
                }
            } catch (InterruptedException e) {
                System.out.print("Interrupted");
            }
        }
    
        public static void main(String[] args) throws Exception {
            ExecutorService exec = Executors.newCachedThreadPool(new DaemonThreadFactory());
            for (int i = 0; i < 10; i++)
                exec.execute(new DaemonThread());
            TimeUnit.MILLISECONDS.sleep(500);
        }
    }
    

    スレッドインタラクション

  • にはスレッドAとスレッドBがあり、スレッドAでB.join()が呼び出されると、スレッドBが終了するまでスレッドAはここで保留されます.
  • にはスレッドAとスレッドBがあり、スレッドAでB.interrupt()を呼び出すとスレッドBが中断して例外が放出される.

  • 例外プロセッサ

    class ExceptionThread implements Runnable {
        public void run() {
            Thread t = Thread.currentThread();
            throw new RuntimeException();
        }
    }
    
    //  Thread.UncaughtExceptionHandler 
    class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println("ViAritcPtiln'e");
    
        }
    }
    
    class HandlerThreadFactory implements ThreadFactory {
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            //  
            t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
            return t;
        }
    }
    
    public class CaptureUncaughtException {
        public static void main(String[] args) {
            //  
            // Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
            ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
            exec.execute(new ExceptionThread());
        }
    }