moc 发表于 2019-1-13 22:31:34

Java032-线程池、定时器

本帖最后由 moc 于 2019-1-13 22:53 编辑

1、线程组
把多个线程组合到一起,对一批线程进行分类管理,Java允许程序直接对线程组进行控制。
// 线程子类
public class MyRunnable implements Runnable {
        @Override
        public void run() {
                for (int x = 0; x < 100; x++) {
                        System.out.println(Thread.currentThread().getName() + ":" + x);
                }
        }
}
// 测试类
public class ThreadGroupDemo {
        public static void main(String[] args) {       
                MyRunnable my = new MyRunnable();
                Thread t1 = new Thread(my, "小明");
                Thread t2 = new Thread(my, "小华");

                // public final ThreadGroup getThreadGroup()查看线程属于哪个组,获得线程组
                ThreadGroup tg1 = t1.getThreadGroup();
                ThreadGroup tg2 = t2.getThreadGroup();
               
                // public final String getName()   查看线程组的名称
                String name1 = tg1.getName();
                String name2 = tg2.getName();
                System.out.println(name1);
                System.out.println(name2);
                System.out.println(Thread.currentThread().getThreadGroup().getName());
                // 通过结果知道:线程默认情况下属于main线程组
                // 通过下面的测试,你应该能够看到,默任情况下,所有的线程都属于同一个组
               
                // ThreadGroup(String name)   创建新的分组
                ThreadGroup tg = new ThreadGroup("这是一个新的组");
               
                // Thread(ThreadGroup group, Runnable target, String name)
                Thread t3 = new Thread(tg, my, "小王");
                Thread t4 = new Thread(tg, my, "小刘");
               
                System.out.println(t1.getThreadGroup().getName());
                System.out.println(t2.getThreadGroup().getName());
               
                //通过组名称设置后台线程,表示该组的线程都是后台线程
                tg.setDaemon(true);
        }
}2、线程池简介
1. 线程池的优点
        ① 线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用。
        ③ 可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃。
2. 线程池的实现原理
提交一个任务到线程池中,线程池的处理流程如下:
        ① 当提交一个任务时,线程池创建一个新线程并执行任务,直到当前线程数等于核心线程数(corePoolSize),等于后再有任务进入②;
        ② 线程池判断工作队列是否已满,如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入③;
        ③ 判断线程池里的线程是否都处于工作状态,如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。
四种线程池:
public static ExecutorService newCachedThreadPool() --------------------------------------> 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
public static ExecutorService newFixedThreadPool(int nThreads)-------------------------> 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) ----> 创建一个定长线程池,支持定时及周期性任务执行。
public static ExecutorService newSingleThreadExecutor() -----------------------------------> 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
3、线程实现方式3:实现Callable接口
步骤:
        ① 创建一个线程池对象,控制要创建几个线程对象,线程池可以执行Runnable对象或者Callable对象代表的线程;
        ② 实现Callable 接口的类;
        ③ 调用如下方法即可 submit方法;
        ④ 结束线程池。
线程求和案例:
// Callable 接口实现类;
public class MyCallable implements Callable<Integer> {
        private int number;
        public MyCallable(int number) {
                this.number = number;
        }

        @Override
        public Integer call() throws Exception {
                int sum = 0;
                for (int x = 1; x <= number; x++) {
                        sum += x;
                }
                return sum;
        }
}
// 测试类
ublic class CallableDemo {
        public static void main(String[] args) throws InterruptedException, ExecutionException {
                // 创建线程池对象
                ExecutorService pool = Executors.newFixedThreadPool(2);

                // 可以执行Runnable对象或者Callable对象代表的线程
                Future<Integer> f1 = pool.submit(new MyCallable(100));
                Future<Integer> f2 = pool.submit(new MyCallable(200));

                // V get()
                Integer i1 = f1.get();
                Integer i2 = f2.get();

                System.out.println(i1);
                System.out.println(i2);

                // 结束
                pool.shutdown();
        }
}4、匿名内部类实现多线程
这种方式用于只执行一次的复杂任务。
本质:是该类或者接口的子类对象。
public class ThreadDemo {
        public static void main(String[] args) {
                // 继承Thread类来实现多线程
                new Thread() {
                        public void run() {
                                for (int x = 0; x < 10; x++) {
                                        System.out.println(Thread.currentThread().getName() + ":" + x);
                                }
                        }
                }.start();

                // 实现Runnable接口来实现多线程
                new Thread(new Runnable() {
                        @Override
                        public void run() {
                                for (int x = 0; x < 10; x++) {
                                        System.out.println(Thread.currentThread().getName() + ":" + x);
                                }
                        }
                }) {
                }.start();

                // 都写啦,只会执行继承来的,即world那一个
                new Thread(new Runnable() {
                        @Override
                        public void run() {
                                for (int x = 0; x < 10; x++) {
                                        System.out.println("hello" + ":" + x);
                                }
                        }
                } {
                        public void run() {
                                for (int x = 0; x < 100; x++) {
                                        System.out.println("world" + ":" + x);
                                }
                        }
                }.start();
        }
}
5、定时器
让我们在指定的时间做某件事情或固定时间间隔重复性做某件事情。
包: java.util.Timer、java.util.TimerTask
方法:
Timer: 定时
Timer( [,boolean isDaemon])------------------------------>   构造函数,创建一个计时器,【指定相关的线程的名称】,【指定作为守护线程运行】
public void schedule(TimerTask task, long delay) ------------------------>安排在指定延迟后执行指定的任务。
public void schedule(TimerTask task,long delay,long period) ---------->安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。
public void cancel()----------------------------------------------------------->终止此计时器,丢弃所有当前已安排的任务。
public void schedule(TimerTask task, Date firstTime[,long period]) --->安排指定的任务在指定的时间【开始进行重复的固定】延迟执行。
TimerTask: 任务
public abstract void run()--------> 此计时器任务要执行的操作。
public boolean cancel() ---------->取消此计时器任务。
// 定时器任务
class MyTask extends TimerTask {
        @Override
        public void run() {
                System.out.println("beng,爆炸了");
        }
}
// 测试类
public class TimerDemo2 {
        public static void main(String[] args) {
                // 创建定时器对象
                Timer t = new Timer();
                // 3秒后执行爆炸任务第一次,每隔2秒再继续炸
                t.schedule(new MyTask2(), 3000, 2000);
        }
}

安迪童童 发表于 2019-1-17 11:25:24

{:10_249:}
页: [1]
查看完整版本: Java032-线程池、定时器