day38 线程池,反射

一、线程池

线程池就是一个提前创建好的容器

线程池技术就是一个可以复用线程的技术

②线程池的类

jdk1.5提供了代表线程池的接口

线程池的具体操作 5步

建立线程池

创建线程

建立任务 

提交任务

关闭线程   

建立任务的几种方法

class MyTask implements Runnable  实现Runnable接口
 ExecutorService es = Executors.newFixedThreadPool(2);
        MyTask m1 = new MyTask("111");
        MyTask m2 = new MyTask("!!!");
        MyTask m3 = new MyTask("333");
        MyTask m4 = new MyTask("^^^");
        es.submit(m1,m2);
        es.submit(m3,m4);
        es.shutdown();
class MyCallable implements Callable 
 实现Callable接口,好处是可以抛异常和有返回值 
    ExecutorService es = Executors.newFixedThreadPool(2);
        MyCallable m1 = new MyCallable("!!!");
        MyCallable m2 = new MyCallable("@@@");
        MyCallable m3 = new MyCallable("$$$");
        MyCallable m4 = new MyCallable("%%%");
        es.submit(m1);
        es.submit(m2);
        es.submit(m3);
        es.submit(m4);
        es.shutdown();

线程池的底层原理

 new ThreadPoolExecutor(
 nThreads, -------> 核心线程数 2
 nThreads, -------> 最大线程数 5                            
 0L, -------------> 指定临时线程最大存活时间
 TimeUnit.MILLISECONDS,-->指定临时线程存活的时间单位(天 ,时 ,分 ,秒)
 new LinkedBlockingQueue(),--> 指定队列任务
 ThreadFactory threadfactort ,---->线程工厂 指定工厂创建线程 
 RejectedExecutionHandler handler );----->线程满且任务忙  此时新任务该如何处理
    ExecutorService es  = new ThreadPoolExecutor(
                3,
                5,
                7L,
                TimeUnit.MICROSECONDS,
                new LinkedBlockingQueue<>(2),
                Executors.defaultThreadFactory(),//使用创建新线程的默认工厂
                new ThreadPoolExecutor.AbortPolicy()//任务处理策略//如果有新任务拒绝处理
        );
        
        MyCallable n1 = new MyCallable("1");
        MyCallable n2 = new MyCallable("!");
        MyCallable n3 = new MyCallable("#");
        MyCallable n4 = new MyCallable("%");
        MyCallable n5 = new MyCallable("¥");
        MyCallable n6 = new MyCallable("……");
        MyCallable n7 = new MyCallable("a");
        MyCallable n8 = new MyCallable("b");
        MyCallable n9 = new MyCallable("c");
        MyCallable n10 = new MyCallable("d");


        es.submit(n1);
        es.submit(n2);
        es.submit(n3);
        es.submit(n4);
        es.submit(n5);
        es.submit(n6);
        es.submit(n7);
        es.submit(n8);
        es.submit(n9);
        es.submit(n10);

      es.shutdown();

新任务拒绝策略
               

 *  ThreadPoolExecutor.AbortPolicy    丢弃任务并抛出RejectedExecutionException异常
 *  ThreadPoolExecutor.DiscardPolicy  丢弃任务,但是不会抛出异常
 *  ThreadPoolExecutor.CallerRunsPolicy  由主线程负责调用任务的run方法从而绕过线程池来处理新任务
 *  ThreadPoolExecutor.DiscardOldestPolicy 抛弃队列中排队时间最久的任务,然后把当前任务加入到队列中

线程池工作原理
 *  1. 线程池的核心组件是线程池管理器(ThreadPoolManager),它负责线程池的创建,销毁和任务调度等功能
 *      线程池管理器会根据传入的参数,创建一定数量的线程,并将这些线程放入到线程池中
 *
 *  2. 线程池中的线程是一种线程池线程(Pool Thread), 由线程池管理器维护,可以重用,线程池在线程
 *      执行任务之前,会反复从任务队列中获取任务并执行,当线程执行完成之后,会检查是否有新的任务需要执行
 *      如果没有,线程会等待新任务的到来
 *
 * 3. 线程池中的人物队列是一个有序的阻塞队列(Blocking Queue), 它用来保存等待执行的任务,当线程池线程获取
 *      任务时,会从队列中取出一个任务并执行,如果队列为空,线程池中的线程则进入等待状态,直到有新的任务加入
 *
 * 4. 线程池的优点:可以通过对线程的复用,减少创建和销毁线程的开销,提高系统的性能和资源的利用率,另外线程池还可以限制
 *    系统中同时执行的线程数量,防止系统资源被过量消耗
 *
 * 总结来说: 线程池的工作原理就是通过线程池管理创建一定数量的线程,并将这些线程放入线程池中,线程池中的
 * 线程会反复从任务队列中获取任务并执行,如果队列为空,线程会等待新任务的到来,通过这种方式,线程池可以提高
 * 系统的性能和资源的利用率

二、反射

  获取一个类的类对象有三种方式


         *  方式一: 类名.class


         *      Class cls = String.class; //获取String的类对象
         *      Class cls = int.class; //获取int的类对象


         *  方式二: Class.forName(String className)


         *      class cls = Class.forName("java.lang.String");
         *      指定的参数为类的完全限定名: 格式:包名 + 类名


         *  方式三:使用ClassLoader类加载器完成

 *      ClassLoader scl = ClassLoader.getSystemClassLoader();
         *      Class aClass = scl.loadClass("java.lang.String");
         *      System.out.println(aClass);
         *


       
         *  方式四: 对象名.getClass()


         *       String str = "我是中国人";
         *       Class aClass = str.getClass();
         *       System.out.println(aClass);
         */

 反射类对象能调用的方法(注意类对象调用方法参数类型是类对象

        //创建类对象

    Class cls = Class.forName("com.oracle.pojo.Student");

          //创建类对象类的 对象

    /**
         * Class调用newInstance()方法创建实例是通过
         * 关联的Java类的无参构造创建的,如果对应的类
         * 没有无参构造会抛出异常
         */
        Student o = (Student) cls.newInstance();

           //想直接创建有参构造的对象使用constructor对象下的newInstance方法

          (注意方法参数是类对象

    Class aClass = Class.forName("com.oracle.pojo.Student");
    Constructor constructor = aClass.getConstructor(Integer.class, String.class, String.class);
    constructor.newInstance(1,"任可","襄阳");

        //全限定名


        String name = cls.getName();
        System.out.println(name);

        String simpleName = cls.getSimpleName();
        System.out.println(simpleName);  //类名

        //获取类的包名


        Package aPackage = cls.getPackage();
        System.out.println(aPackage);

        //获取父类的类对象


        Class superclass = cls.getSuperclass();
        System.out.println(superclass);

        //获取接口


        Class[] interfaces = cls.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println(anInterface);
        }

        System.out.println("----------------------------");

        //获取所有的public修饰的属性,包括继承的


        Field[] fields = cls.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }

        //通过属性名获取


        Field id = cls.getField("id");
        System.out.println(id);

     

        //获取所有的自定义属性,


        Field[] files = cls.getDeclaredFields();
        for (Field file : files) {
            System.out.println(file.getName());
        }

        //通过属性名获取


        Field gender = cls.getDeclaredField("gender");
        System.out.println(gender);

  
        //获取属性的类型


        Field file = cls.getField("address");
        Class type = file.getType();
        System.out.println(type.getSimpleName());

        //获取属性的修饰符


        int i = file.getModifiers();
        String str = Modifier.toString(i);
        System.out.println(str);

        //给属性赋值


        Field id1 = cls.getField("id");
        id1.set(o,1);

        Field field = cls.getDeclaredField("name");
        System.out.println(field.getName());


        field.setAccessible(true); //强制获取权限


        field.set(o,"张三");//设置对象的属性

        Object o1 = id1.get(o);//获取对象的属性
        

        Object o2 = field.get(o);
        System.out.println(o2); //张三

        //获取类对象下的方法;

        调用方法(用该类的对象执行此方法)

        Class aClass = Class.forName("com.oracle.pojo.Person");
        Object o1 = aClass.newInstance();
        Person o = (Person) o1;

        Method say = aClass.getMethod("say");
        say.invoke(o);

             

        //获取类对象下的有参的 public方法;

      用该类的对象加参数执行此方法(注意方法参数是类对象

Class aClass = Class.forName("com.oracle.pojo.Person");
Object o1 = aClass.newInstance();
Person o = (Person) o1;
Method say1 = aClass.getMethod("say", String.class);
say1.invoke(o,"哈哈");

          //获取所有自定义的方法

aClass.getDeclaredMethods()

             //获取所有public方法

 aClass.getMethods();

                //获取属性的修饰符

                xxx.getMedifiers()

 三、终极练习

自动执行与当前Test类在同一包下类所有无参方法

day38 线程池,反射_第1张图片

package com.oracle.pojo;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URISyntaxException;

/**
 * 自动执行与当前类在同一包下类所有无参方法
 */
public class Test {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, URISyntaxException {
       //获取当前类所在路径
        File file = new File(Test.class.getResource(".").toURI());
        //获取当前路径下所有文件
        File[] files = file.listFiles();
        //判断是否为.class文件  获取文件名  substring()
        for (File file1 : files) {
            if (file1.getName().endsWith(".class")){
                String sb = file1.getName().substring(0,file1.getName().lastIndexOf("."));

                Class aClass = Class.forName("com.oracle.pojo."+sb);
//        Class aClass1 = Class.forName("com.oracle.pojo.Student");
                Object o = aClass.newInstance();

                Method[] declaredMethods = aClass.getDeclaredMethods();
                for (Method declaredMethod : declaredMethods) {
                    if (declaredMethod.getParameterCount() == 0){
                        if (declaredMethod.getModifiers() == Modifier.PUBLIC){
                            declaredMethod.invoke(o);
                        }else {
                            declaredMethod.setAccessible(true);
                            declaredMethod.invoke(o);
                        }
                    }
                }
            }
            }
        }

你可能感兴趣的:(java,开发语言)