多线程之四大拒绝策略

定义拒绝策略,需要重写RejectedExecutionHandler接口的rejectedExecution(Runnable r, ThreadPoolExecutor executor);方法。

public interface RejectedExecutionHandler {


      void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

AbortPolicy策略

该策略直接抛出异常。

public static class AbortPolicy implements RejectedExecutionHandler {
               public AbortPolicy() {         public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }

注意:使用此拒接策略,切记ThreadPoolExecutor.execute需要try catch,否则程序会直接退出。


CallerRunsPolicy策略

public static class CallerRunsPolicy implements RejectedExecutionHandler {
               public CallerRunsPolicy() { }

            public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }

从源码可以看出:只要线程池未关闭,该策略直接在调用者线程(如Main方法)中运行当前被丢弃的任务。显然这样不会真的丢弃任务,但是,调用者线程性能可能急剧下降。


DiscardPolicy策略

public static class DiscardPolicy implements RejectedExecutionHandler {
               public DiscardPolicy() { }

                public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }

默默的丢弃无法处理的任务,不予任何处理。


DiscardOldestPolicy策略

丢弃最老的一个请求任务,也就是丢弃一个即将被执行的任务,并尝试再次提交当前任务。

 public static class DiscardOldestPolicy implements RejectedExecutionHandler {
               public DiscardOldestPolicy() { }

               public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }

一般在实际开发中,根据业务需求,自定义拒绝策略。

<think>好的,我现在需要回答用户关于Java语言特性的问题,特别是用户提到的四个方面:跨平台、面向对象、垃圾自动回收和多线程。用户之前已经询问过Java的语言特性,现在希望更深入地了解这四个方面,同时还要解释“准动态”、“强类型”和“解释型语言”这些术语,并分别展开介绍。 首先,我需要确认用户的具体需求。用户可能正在准备面试,或者在学习Java的基础知识,想要更详细地了解这些核心概念。之前的回复已经详细列出了Java的多个特性,但用户这次特别指定了四个主要特性,所以需要针对这四个方面进行详细展开,同时还要解释另外三个语言特性相关的术语。 接下来,我需要回顾Java的跨平台特性。跨平台主要依赖于JVM(Java虚拟机),用户可能已经知道这一点,但需要更详细地解释JVM如何工作,字节码的作用,以及为什么Java被称为“一次编写,到处运行”。需要提到不同操作系统上的JVM实现,以及JVM如何将字节码转换为特定平台的机器码。 然后是面向对象。需要详细说明Java的OOP特性,包括封装、继承、多态,可能还要提到抽象类与接口的区别,以及这些特性如何促进代码的模块化和重用。用户可能希望了解这些概念在实际编程中的应用,例如如何通过继承减少代码冗余,或者多态如何提高代码的灵活性。 垃圾自动回收机制是另一个重点。需要解释GC的基本原理,如如何判断对象是否可回收(引用计数、可达性分析),不同的垃圾回收算法(如分代收集、标记-清除、复制算法等),以及这些算法如何影响性能。可能还需要提到不同的垃圾回收器(如Serial、Parallel、CMS、G1)及其适用场景,以及如何通过JVM参数进行调优。 多线程方面,需要介绍Java中的线程创建方式(继承Thread类、实现Runnable接口、Callable/Future),线程池的使用,同步机制(synchronized关键字、Lock接口、volatile变量),以及并发工具包(如CountDownLatch、CyclicBarrier、ConcurrentHashMap)。用户可能想知道Java如何处理线程安全,以及如何避免死锁和竞态条件。 关于用户提到的三个语言特性:准动态、强类型、解释型语言。这里需要分别解释每个术语的含义,并说明它们如何应用于Java。例如,Java虽然是静态类型语言,但通过反射机制实现了一定程度的动态性,因此被称为“准动态”。强类型指的是变量类型在编译时确定且不能随意转换,解释型语言则可能指Java代码通过JVM解释执行,但实际情况是JIT编译器将字节码编译为本地机器码,所以可能需要澄清Java是编译型还是解释型,或者两者的结合。 在组织内容时,需要确保结构清晰,每个部分有明确的标题和要点,使用用户容易理解的例子或场景。同时,要注意避免重复之前已经提供的信息,但可能需要简要回顾以确保连贯性。 最后,需要检查是否有遗漏的重要细节,例如跨平台的实际应用案例,垃圾回收的优缺点,多线程中的常见问题及解决方案,以及准动态特性的实际应用(如框架中的反射使用)。确保每个部分的解释准确且深入浅出,适合不同层次的理解者。---</think> ### **一、语言特性:准动态、强类型、解释型语言** 以下是与 Java 相关的语言特性术语的详细说明: #### **1. 准动态(Quasi-Dynamic)** - **定义**:Java 本质是静态语言,但通过反射(Reflection)等机制,可以在运行时动态获取类信息、调用方法或修改字段,实现类似动态语言的灵活性。 - **框架设计**:Spring 通过反射创建 Bean 并注入依赖。 - **动态代理**:AOP(面向切面编程)生成代理对象,拦截方法调用。 - **示例代码**: ```java Class<?> clazz = Class.forName("com.example.MyClass"); Method method = clazz.getMethod("myMethod"); Object instance = clazz.newInstance(); method.invoke(instance); ``` - **局限性**:反射性能较低,且破坏封装性,需谨慎使用。 #### **2. 强类型(Strongly Typed)** - **定义**:变量类型在编译时严格检查,类型转换需显式声明(如强制转换),避免隐式类型错误。 - **特点**: - **编译时检查**:例如 `int a = "123";` 直接报错,无法通过编译。 - **类型安全**:减少运行时类型错误(如 `ClassCastException`)。 - **对比弱类型语言**:JavaScript 中 `"5" + 1` 结果为 `"51"`,而 Java 会直接拒绝此类操作。 #### **3. 解释型语言** - **定义**:Java 源码先编译为字节码(`.class`),再由 JVM 逐行解释执行。 - **与编译型语言的区别**: - **C/C++**:直接编译为机器码,运行效率高,但跨平台性差。 - **Java**:字节码是中间层,依赖 JVM 解释或 JIT 编译(运行时优化)。 - 高频代码(如循环)会被 JIT 编译为本地机器码,提升性能。 - 平衡了启动速度和长期运行效率。 --- ### **二、Java 四大核心特性详解** #### **1. 跨平台(Write Once, Run Anywhere)** - **实现原理**: - **字节码与 JVM**:Java 源码编译为与平台无关的字节码(`.class`),由不同平台的 JVM 解释执行。 - **JVM 适配**:各操作系统(Windows、Linux、macOS)需安装对应版本的 JVM。 - **示例流程**: 1. 开发者编写 `HelloWorld.java`。 2. 编译生成 `HelloWorld.class`(字节码)。 3. Windows 上的 JVM 解释执行该字节码,输出结果。 4. 同一字节码在 Linux 的 JVM 上直接运行,无需修改代码。 - **局限性**: - JVM 本身是平台相关的,需为不同系统单独安装。 - 依赖本地方法(Native Methods,如 JNI)时可能破坏跨平台性。 #### **2. 面向对象(OOP)** - **四大核心特性**: - **封装**:隐藏内部实现细节,通过 `private`/`public` 控制访问权限。 ```java public class Person { private String name; // 封装字段 public String getName() { return name; } // 提供公共方法访问 } ``` - **继承**:子类复用父类属性和方法(单继承)。 ```java class Animal { void eat() { /* ... */ } } class Dog extends Animal { /* 继承 eat() 方法 */ } ``` - **多态**:同一方法在不同对象中有不同行为(覆盖、重载)。 ```java Animal a = new Dog(); a.eat(); // 调用 Dog 类的 eat() 方法(动态绑定) ``` - **抽象**:通过抽象类(`abstract class`)和接口(`interface`)定义规范。 - **优势**:提高代码复用性、可维护性,降低模块耦合。 #### **3. 垃圾自动回收(GC)** - **基本原理**: - **可达性分析**:从根对象(如栈局部变量、静态变量)出发,标记所有存活对象,回收不可达对象。 - **分代收集**:堆内存分为新生代(Young Generation)和老年代(Old Generation),采用不同回收策略。 - **新生代**:使用复制算法(Survivor 区)。 - **老年代**:使用标记-清除或标记-整理算法。 - **GC 触发条件**: - 新生代满时触发 Minor GC。 - 老年代满时触发 Full GC(停顿时间长,需优化避免)。 - **常见垃圾回收器**: - **Serial GC**:单线程,适合客户端应用。 - **Parallel GC**(默认):多线程,吞吐量优先。 - **CMS**:低停顿,已弃用。 - **G1 GC**:分区回收,平衡吞吐量和延迟。 - **调优建议**:避免频繁 Full GC,合理设置堆大小(`-Xms`/`-Xmx`),选择合适的 GC 算法。 #### **4. 多线程** - **线程创建方式**: - **继承 `Thread` 类**: ```java class MyThread extends Thread { public void run() { /* 线程逻辑 */ } } new MyThread().start(); ``` - **实现 `Runnable` 接口**(推荐,避免单继承限制): ```java Runnable task = () -> { /* 线程逻辑 */ }; new Thread(task).start(); ``` - **线程池(`ExecutorService`)**: ```java ExecutorService executor = Executors.newFixedThreadPool(4); executor.submit(task); ``` - **线程同步**: - **`synchronized` 关键字**:锁定对象或类,保证原子性。 ```java public synchronized void increment() { count++; } ``` - **`Lock` 接口**:更灵活的锁控制(如 `ReentrantLock`)。 - **`volatile` 变量**:保证可见性,禁止指令重排序。 - **并发工具包(`java.util.concurrent`)**: - **`ConcurrentHashMap`**:线程安全的哈希表,分段锁提升并发度。 - **`CountDownLatch`**:等待多个线程完成后再继续。 - **`Future` 和 `CompletableFuture`**:异步任务结果处理。 - **常见问题**: - **死锁**:避免嵌套锁,按固定顺序获取锁。 - **线程安全**:使用原子类(如 `AtomicInteger`)替代 `synchronized`。 --- ### **总结** Java 的四大特性使其成为企业级开发的基石: - **跨平台**:依赖 JVM,一次编译处处运行。 - **面向对象**:通过封装、继承、多态构建模块化代码。 - **垃圾回收**:自动管理内存,降低开发者负担。 - **多线程**:内置并发工具支持高性能应用开发。 理解这些特性,能更好地掌握 Java 的核心设计思想和技术优势。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值