线程池就是一个提前创建好的容器
线程池技术就是一个可以复用线程的技术
②线程池的类
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类在同一包下类所有无参方法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); } } } } } }