浅谈java中继承Thread与实现Runable的区别

本文探讨Java中实现多线程的两种方法:继承Thread类与实现Runnable接口。详细比较了它们的优缺点,如资源共享、类继承限制及线程控制能力,为开发者选择合适的多线程实现方式提供指导。

    java中现实多线程可以继承Thread,也可以实现Runable;

    一般的用法都是重写或实现run方法,然后用Tread调用start方法(注意,只有Thread有start方法;Runable是没有start方法的);

    在我们通常简单的用多线程时尽量通过实现Runable的方式;因为实现R相对于继承T有如下有点:

    1. 继承了T后不能再继承别的类,但实现R的同时可以再继承其他某个类,然而两者都实现了简单的多线程,所以R有此优势;

    2. 实现了R后可以资源共享,而继承了T后不能资源共享(共享指的是共同操作类的成员变量(当然是非静态变量,静态的肯定都能共享));因为继承了T后每次使用时都创建新的类,而实现R后每次使用时创建了新的Thread,但创建这些Thread是可以用同一个Runable,所以可以共享;此乃第二个有点;

    然而继承Thread不可能一无是处,否则就没必要存在这种方式了;

    事实上Runable提供了run方法(Thread的run也是实现了Runable),而Thread中是有各种线程实现、管理的方法,start是其中一个方法,用来提供启动线程的方法;

    所以,当现有的多线程方式Thread不能满足你的要求,你需要修改或优化Thread时,必须要继承Thread了,因为很多对线程相关的的东西是在Thread中实现的;这个是Thread存在的必要,也即优势;

    总之,想要继承别的类,或想要简单共享资源就用Runable,(当然,我觉得Thread通过别的方式应该也可以实现资源共享的);想要优化线程时可以继承Thread; 一般情况用Runable,没有特定需求是两者都可用;

OVER;

 

<think>好的,我现在需要回答用户关于Java中Map的value为Runnable类型的问题。首先,我得理解用户的需求,他们可能想了解如何在Map中使用Runnable作为值,以及这种结构有什么应用场景。 首先,我应该回忆一下Java中的Map接口,它存储键值对。Runnable是一个函数式接口,只有一个run()方法,通常用于多线程编程。当Map的value是Runnable时,每个键对应的值都是一个可执行的任务。 接下来,我需要考虑用户可能的疑惑点,比如如何创建这样的Map,如何添加Runnable实例,以及如何调用它们的run方法。可能需要一个具体的例子来说明,这样用户更容易理解。 然后,我应该解释应用场景,比如任务调度,根据不同的键执行不同的任务,或者在配置多个可执行的操作时使用。例如,一个命令行程序根据不同的命令执行对应的Runnable任务。 还要注意线程安全的问题,因为Runnable通常和线程一起使用。但Map本身如果是非线程安全的实现,比如HashMap,在多线程环境下可能需要使用ConcurrentHashMap或者进行同步处理。 另外,可能需要提到Java 8之后的lambda表达式,可以更简洁地创建Runnable实例,这样添加到Map中的代码会更简洁。 最后,总结这种结构的优势和注意事项,帮助用户全面理解。需要确保步骤清晰,示例正确,语法无误,并且用中文口语化的方式表达,避免使用专业术语过多,但必要术语还是需要正确使用。</think>在Java中,当`Map`的value类型为`Runnable`时,意味着这个Map的每个键(key)对应一个可执行的任务。以下是逐步说明: --- ### 1. **基本概念** - **`Runnable`接口**:Java中用于定义多线程任务的接口,仅包含一个抽象方法`run()`。 ```java @FunctionalInterface public interface Runnable { void run(); } ``` - **`Map`结构**:键值对集合,此处键可以是任意类型(如`String`),值类型固定为`Runnable`。 --- ### 2. **典型用途** - **任务调度**:通过键快速获取并执行对应的任务。 - **动态行为配置**:例如根据用户输入选择不同操作。 --- ### 3. **代码示例** #### 步骤1:定义Map并填充任务 ```java Map<String, Runnable> taskMap = new HashMap<>(); // 添加任务方式1:匿名内部类 taskMap.put("task1", new Runnable() { @Override public void run() { System.out.println("执行任务1"); } }); // 添加任务方式2:Lambda表达式(Java 8+) taskMap.put("task2", () -> System.out.println("执行任务2")); ``` #### 步骤2:根据键获取并执行任务 ```java Runnable task = taskMap.get("task1"); if (task != null) { // 直接运行(当前线程) task.run(); // 或启动新线程执行 new Thread(task).start(); } ``` --- ### 4. **实际应用场景** - **命令行工具**:根据命令名称触发不同操作。 ```java taskMap.put("help", () -> showHelp()); taskMap.put("exit", () -> System.exit(0)); ``` - **游戏逻辑**:根据事件类型触发不同响应。 ```java taskMap.put("playerJump", () -> jumpAction()); taskMap.put("playerAttack", () -> attackAction()); ``` --- ### 5. **注意事项** - **线程安全**: - 若多个线程修改Map,需使用`ConcurrentHashMap`。 - `Runnable`本身不保证线程安全,需自行实现同步。 - **空值检查**:调用`map.get(key)`可能返回`null`,需做判空处理。 --- ### 6. **扩展:结合函数式编程** Java 8+允许更简洁的写法: ```java Map<String, Runnable> advancedMap = Map.of( "save", () -> saveData(), "load", () -> loadData() ); ``` --- 通过这种方式,你可以灵活地管理和触发多个任务,适用于需要动态行为管理的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值