美文网首页
★18.并发

★18.并发

作者: iDragonfly | 来源:发表于2017-07-03 19:56 被阅读0次

    定义线程类

    方式一: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();
            }
        }
    }
    

    方式三: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();
        }
    }
    

    方式三:Callable

    • 相比Runnable接口,Callable接口可以从线程中返回一个值,这个值通过Future对象包装
    class TaskWithResult implements Callable<String> {
        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<Future<String>> results = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                results.add(exec.submit(new TaskWithResult(i)));
            }
            for (Future<String> 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);
    

    方式二

    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(),则线程A会在此处挂起直至线程B结束。
    • 有线程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());
        }
    }
    

    相关文章

      网友评论

          本文标题:★18.并发

          本文链接:https://www.haomeiwen.com/subject/vzuzcxtx.html