线程(并发)

  1. 线程的创建方式
    class TaskWithResult implements Callable<String>{
        private int id;
    
        public TaskWithResult(int id) {
            this.id = id;
        }
        @Override
        public String call() throws Exception {
            return "result of taskResult is " +id;
        }
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newCachedThreadPool();
            List<Future<String>> list = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                Future<String> future = executorService.submit(new TaskWithResult(i));
                list.add(future);
            }
            try {
                for (Future<String> future : list) {
                    if(future.isDone()){
                        System.out.println(future.get());
                    }//也可以直接调用get方法,这个时候get会被阻塞,直到task完成之后才被执行 
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
    public class TestRunable implements Runnable{
       protected int countDown = 10;
       private static int taskCount = 0;//当前运行的线程计数
       private final int id = taskCount++;//当前线程id标记
       public String status() {
            return "#" + id + "(" + (countDown > 0 ? countDown : "lifeOff") + ")." + taskCount;
       }
       @Override
       public void run() {
          while (countDown >= 0) {
             System.out.println(status());
             Thread.yield();
             countDown--;
          }
       }
       public static void main(String[] args){
           for(int i=0;i<5;i++) {
               Thread t = new Thread(new LifeOff());
               t.start();
           }
       }
    }
    public class TestThread extends Thread{
       protected int countDown = 10;
       private static int taskCount = 0;//当前运行的线程计数
       private final int id = taskCount++;//当前线程id标记
       public String status() {
            return "#" + id + "(" + (countDown > 0 ? countDown : "lifeOff") + ")." + taskCount;
       }
       public void run(){
          while(countDown >= 0){
             System.out.println(status());
             Thread.yield();
             countDown--;
          }
       }
       public static void main(String[] args){
           for(int i=0;i<5;i++){
               Thread a = new TestThread();
               a.start();
           }
       }
    }

     

  2. java线程管理(线程包装器Executors)
    class LifeOff implements Runnable {
        protected int countDown = 10;
        private static int taskCount = 0;
        private final int id = taskCount++;
    
        public LifeOff() {}
    
        public LifeOff(int countDown) {
            this.countDown = countDown;
        }
    
        public String status() {
            return "#" + id + "(" + (countDown > 0 ? countDown : "lifeOff") + ")." + taskCount;
        }
    
        @Override
        public void run() {
            while (countDown >= 0) {
                System.out.println(status());
                Thread.yield();
                countDown--;
            }
        }
    }
    public class JunitTest{
       public void static main(String[] args){
           //创建一个最小线程未0,最大为2的31次方-1,存活时间为60s(空闲线程的存活时间)的线程池
           //会创建和所需数量相同的线程(一个任务对应一个线程),在回收线程时(当线程超过最大容量,且闲置时间超过设置的时间时)停止创建线程
           //是相对合理的线程管理对象
           ExecutorService service = Executors.newCachedThreadPool();
           //当newCachedThreadPool可能会发生问题时,应该考虑另一种方式(指定创建的线程数量)
           ExecutorService service = Executors.newFixThreadPool(3);
           //当需要在某一个线程中长期运行某个任务时,你需要使用SingleThreadExecutor,这个是线程数量为1的FixedTheadPool
           //任何时间任何线程都只有一个任务在运行
           ExecutorService service = Executors.newSingleThreadExecutor();
           for(int i=0;i<5;i++){
               service.execute(new LifeOff());
           }
           service.shutdown();
       }
    }

     

  3. 优先级(听起来好像很高大上,但是我能说没看懂么,测试貌似没什么卵用)
    class SimplePriorities implements Runnable {
        private int countDown = 5;
        private int priority;
        private volatile double d;
    
        public SimplePriorities(int priority) {
            this.priority = priority;
        }
    
        @Override
        public String toString() {
            return Thread.currentThread() + ":" + countDown;
        }
    
        @Override
        public void run() {
            Thread.currentThread().setPriority(priority);
            //通过大量浮点运算,来让线程优先级调度介入,从而主动控制线程(貌似没什么效果,应该还是和OS对CPU调度有关)
            while (true) {
                for (int i = 0; i < 100000; i++) {
                    d += (Math.PI + Math.E) / (double) i;
                    if (i % 1000 == 0) {
                        Thread.yield();
                    }
                }
                System.out.println(this);
                if (--countDown == 0) {
                    return;
                }
            }
        }
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i = 0; i < 5; i++) {
                executorService.execute(new SimplePriorities(Thread.MIN_PRIORITY));
                executorService.execute(new SimplePriorities(Thread.MAX_PRIORITY));
            }
            executorService.shutdown();
        }
    }

     

  4. 后台线程:通过setDaemon(true)可以设置线程未后台运行,且必须在start()调用前设置;且当所有非后台线程结束后(程序终止),后台线程自动结束
    /**
     * 后台线程
     * 当所有非后台线程结束后,则后台线程自动结束
     * 可以通过修改sleep的时间可以明显看到效果
     */
    class SimpleDaemon implements Runnable{
        @Override
        public void run() {
            try {
                //这里写一个死循环,无限执行当前线程的打印
                while (true) {
                    System.out.println(Thread.currentThread()+"..."+this);
                    TimeUnit.MILLISECONDS.sleep(100);//等同Thread.currentThread().sleep(100)
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            for (int i=0;i<10;i++) {
                Thread thread = new Thread(new SimpleDaemon());
                //设置要执行的线程未后台线程:必须在执行前设置
                thread.setDaemon(true);
                thread.start();
            }
            System.out.println("SimpleDaemon start");
            try {
                TimeUnit.MILLISECONDS.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    //通过实现ThreadFactory来设置线程的一些属性,比如优先级、名称、是否为后台线程(priority,name,daemon等)
    class DaemonThreadFactory implements ThreadFactory{
        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setDaemon(true);
            return thread;
        }
    }
    
    class DaemonFromFactory implements Runnable {
        @Override
        public void run() {
            try {
                //这里写一个死循环,无限执行当前线程的打印
                while (true) {
                    TimeUnit.MILLISECONDS.sleep(100);//等同Thread.currentThread().sleep(100)
                    System.out.println(Thread.currentThread()+"..."+this);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) throws Exception {
            //通过Executors.newCachedThreadPool(ThreadFactory f)来设置线程的属性
            ExecutorService executorService = Executors.newCachedThreadPool(new DaemonThreadFactory());
            for (int i=0;i<10;i++) {
                executorService.execute(new DaemonFromFactory());
            }
            System.out.println("SimpleDaemon start");
            TimeUnit.MILLISECONDS.sleep(200);
            executorService.shutdown();
        }
    }

     

  5. 线程协作(wait --- notifyAll)
    /**
     * synchronized wait -- notifyAll方式
     * car的抛光和打蜡的并发操作
     */
    class Car {
        /*打蜡是否OK的标记*/
        private boolean waxOn = false;
        /*已经打好蜡OK了,等待抛光*/
        public synchronized void waxed() {
            waxOn = true;
            notifyAll();
        }
        /*已经抛光OK了,等待打蜡*/
        public synchronized void buffed() {
            waxOn = false;
            notifyAll();
        }
        /*如果未打蜡,则等待打蜡*/
        public synchronized void waitForWax()throws InterruptedException {
            while (waxOn == false) {
                wait();
            }
        }
        /*如果打蜡OK了,则等待抛光*/
        public synchronized void waitForBuffed() throws InterruptedException {
            while (waxOn == true) {
                wait();
            }
        }
    }
     
    /**
     * 打蜡
     */
    class WaxOn implements Runnable {
     
        private Car car;
     
        public WaxOn(Car car) {
            this.car = car;
        }
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    /*先判断当前车是否打蜡OK,如果OK,则修改打蜡标记,然后等待抛光*/
    //                car.waitForWax();
                    car.waxed();
                    System.out.println("打蜡完成。。。");
                    car.waitForBuffed();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
     
    /**
     * 抛光
     */
    class Buffed implements Runnable {
     
        private Car car;
     
        public Buffed(Car car) {
            this.car = car;
     
        }
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    /*先判断是否打蜡OK了,如果打蜡OK,则进行抛光,然后等待打蜡*/
                    car.waitForWax();
                    System.out.println("正在抛光中。。。");
                    car.buffed();
    //                car.waitForWax();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
     
    class CarTest {
     
        public static void main(String[] args) throws InterruptedException{
            Car car = new Car();
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i=0;i<3;i++) {
                executorService.execute(new WaxOn(car));
                executorService.execute(new Buffed(car));
                TimeUnit.MILLISECONDS.sleep(1);
            }
            executorService.shutdownNow();
        }
     
    }
    /**
     * lock方式
     * car的抛光和打蜡的并发操作
     */
    class Car {
        /*打蜡是否OK的标记*/
        private boolean waxOn = false;
        private Lock lock = new ReentrantLock();
        private Condition condition = lock.newCondition();
        /*已经打好蜡OK了,等待抛光*/
        public void waxed() {
            lock.lock();
            try {
                waxOn = true;
                condition.signalAll();
            } finally {
                lock.unlock();/*任何情况下都要保证释放锁*/
            }
        }
        /*已经抛光OK了,等待打蜡*/
        public void buffed() {
            lock.lock();
            try {
                waxOn = false;
                condition.signalAll();
            } finally {
                lock.unlock();
            }
        }
        /*如果未打蜡,则等待打蜡*/
        public void waitForWax()throws InterruptedException {
            lock.lock();
            try {
                while (waxOn == false) {
                    condition.await();
                }
            } finally {
                lock.unlock();
            }
        }
        /*如果打蜡OK了,则等待抛光*/
        public void waitForBuffed() throws InterruptedException {
            lock.lock();
            try {
                while (waxOn == true) {
                    condition.await();
                }
            } finally {
                lock.unlock();
            }
        }
    }
     
    /**
     * 打蜡
     */
    class WaxOn implements Runnable {
     
        private Car car;
     
        public WaxOn(Car car) {
            this.car = car;
        }
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    /*先判断当前车是否打蜡OK,如果OK,则修改打蜡标记,然后等待抛光*/
    //                car.waitForWax();
                    car.waxed();
                    System.out.println("打蜡完成。。。");
                    car.waitForBuffed();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
     
    /**
     * 抛光
     */
    class Buffed implements Runnable {
     
        private Car car;
     
        public Buffed(Car car) {
            this.car = car;
     
        }
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    /*先判断是否打蜡OK了,如果打蜡OK,则进行抛光,然后等待打蜡*/
                    car.waitForWax();
                    System.out.println("正在抛光中。。。");
                    car.buffed();
    //                car.waitForWax();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
     
    class CarTest {
     
        public static void main(String[] args) throws InterruptedException{
            Car car = new Car();
            ExecutorService executorService = Executors.newCachedThreadPool();
            for (int i=0;i<3;i++) {
                executorService.execute(new WaxOn(car));
                executorService.execute(new Buffed(car));
                TimeUnit.MILLISECONDS.sleep(1);
            }
            executorService.shutdownNow();
        }
     
    }
    /**
     * linkedBlockingQueue(阻塞队列)方式
     * 生产吐司、给吐司添加黄油、给吐司添加果酱
     * 吐司
     */
    class Toast {
    
        /*状态:dry空白吐司,buttered添加好黄油的,jamed添加好果酱的*/
        public enum Status {
            DRY("有吐司"), BUTTERED("有黄油"), JAMED("有果酱");
            private String name;
    
            private Status(String name) {
                this.name = name;
            }
    
            public String getName() {
                return name;
            }
        }
    
        private Status status = Status.DRY;
        private int id;
    
        public Toast(int id) {
            this.id = id;
        }
    
        /*添加黄油*/
        public void butted() {
            status = Status.BUTTERED;
        }
    
        /*添加果酱*/
        public void jamed() {
            status = Status.JAMED;
        }
    
        public Status getStatus() {
            return status;
        }
    
        public int getId() {
            return this.id;
        }
    
        @Override
        public String toString() {
            return "Toast " + id + ":" + status.getName();
        }
    }
    
    class ToastQueue extends LinkedBlockingQueue<Toast> {
        /*设置该队列的容量*/
        public ToastQueue(int i) {
            super(i);
        }
    }
    
    /*生产吐司*/
    class Toaster implements Runnable {
    
        private ToastQueue toastQueue;
        private int count = 0;
    
        public Toaster(ToastQueue toastQueue) {
            this.toastQueue = toastQueue;
        }
    
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    Toast toast = new Toast(count++);
                    System.out.println(toast);
                    /*添加到已经生产好toast的队列*/
                    toastQueue.put(toast);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    /*添加黄油的线程*/
    class Buffer implements Runnable {
    
        private ToastQueue bufferQueue;
        private ToastQueue toastQueue;
    
        public Buffer(ToastQueue toastQueue, ToastQueue bufferQueue) {
            this.bufferQueue = bufferQueue;
            this.toastQueue = toastQueue;
        }
    
        private int count = 0;
    
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    /*取出toast,添加黄油,并存放在已经添加完黄油队列*/
                    Toast toast = toastQueue.take();
                    toast.butted();
                    System.out.println(toast);
                    bufferQueue.put(toast);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    class Jamer implements Runnable {
    
        private ToastQueue bufferQueue;
        private ToastQueue jamerQueue;
    
        public Jamer(ToastQueue bufferQueue, ToastQueue jamerQueue) {
            this.bufferQueue = bufferQueue;
            this.jamerQueue = jamerQueue;
        }
    
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    Toast toast = bufferQueue.take();
                    toast.jamed();
                    System.out.println(toast);
                    jamerQueue.put(toast);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("jam finished");
        }
    }
    
    class Finisher implements Runnable {
    
        private ToastQueue jamerQueue;
        private int        count;
    
        public Finisher(ToastQueue jamerQueue) {
            this.jamerQueue = jamerQueue;
        }
    
        @Override
        public void run() {
            try {
                while (!Thread.interrupted()) {
                    Toast toast = jamerQueue.take();
                    if (toast.getId() != count++ || toast.getStatus() != Toast.Status.JAMED) {
                        System.err.println("不是同一块toast,或者没有添加果酱 " + toast);
                        System.exit(1);
                    } else {
                        System.out.println(toast);
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    class ToastTest {
    
        public static void main(String[] args) throws Exception {
            ToastQueue toastQueue = new ToastQueue(1);
            ToastQueue bufferQueue = new ToastQueue(1);
            ToastQueue jamerQueue = new ToastQueue(1);
            ExecutorService executorService = Executors.newCachedThreadPool();
            executorService.execute(new Toaster(toastQueue));
            for (int i = 0; i < 5; i++) {
                executorService.execute(new Buffer(toastQueue, bufferQueue));
                executorService.execute(new Jamer(bufferQueue, jamerQueue));
                executorService.execute(new Finisher(jamerQueue));
            }
            TimeUnit.MILLISECONDS.sleep(50);
            executorService.shutdownNow();
        }
    
    }
    /*
     * 使用管道必须保证输入输出的对象创建完成(如main方法中new2个对象),否则在不同平台会发生不一致问题
     * 理论不建议使用管道来操作线程协作,建议使用BlockQueue更方便,也更安全
     *管道写入端
     * */
    class Sender implements Runnable {
    
        private PipedWriter pipedWriter;
    
        public Sender(PipedWriter pipedWriter) {
            this.pipedWriter = pipedWriter;
        }
        public PipedWriter getPipedWriter() {
            return pipedWriter;
        }
        @Override
        public void run() {
            try {
                while (true) {
                    for (char i = 'A'; i <= 'z'; i++) {
                        pipedWriter.write(i);
                    }
                    TimeUnit.MILLISECONDS.sleep(100);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException ee) {
                ee.printStackTrace();
            }
        }
    }
    /*管道接收端*/
    class Receiver implements Runnable {
    
        private PipedReader reader;
    
        private Sender sender;
    
        public Receiver(Sender sender) throws Exception{
            reader = new PipedReader(sender.getPipedWriter());
        }
        @Override
        public void run() {
            try {
                while (true) {
                    /*使用reader.read()会在线程池调用shutdownNow()时直接截断,无论reader是否有读完*/
                    System.out.println("Read "+reader.read() + ",");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    class PipedMain {
    
        public static void main(String[] args) throws Exception{
            PipedWriter pipedWriter = new PipedWriter();
            Sender sender = new Sender(pipedWriter);
            Receiver receiver = new Receiver(sender);
            ExecutorService service = Executors.newCachedThreadPool();
            service.execute(sender);
            service.execute(receiver);
            TimeUnit.MILLISECONDS.sleep(100);
            service.shutdownNow();
        }
    
    }

     

  6.  

转载于:https://my.oschina.net/qcAtKmTCeCA/blog/727889

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值