浅谈new Runnable(){}--new Interface(){}

   在java多线程中实现多线程的方式有两种①extends Thread ②implements Runnable。这两种情况是我们最常见的,还有一种是由第二种变形而来的直接new Runnable(){},我写这篇博客的目的是来将new Runnable(){}中的机制理一理,让读者更清晰地理解new Runnable(){},下面我就通过代码来将问题演示。
package com.cph.Thread;

public class Text2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
         Runnable runnable=new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                System.out.println("i am new Runnable(){xxx}");

            }
        };
        Thread thread=new Thread(runnable);
        thread.start();
    }

}
    这段代码不会出现什么问题,控制台会输出:i am new Runnable(){xxx}
    但如果java基础扎实一点的朋友,就会疑问Runnable()是接口,我们都知道java的接口是不可以实例化的,但代码中的new Runnable(){xxx}确是实例化了,为什么?
    接口和抽象类不可以实例化是对的,这个是java语法规范来的,**而new Runnable(){}其实不是实例化Runnable接口来的,实际上一种内部类的一种简写**
    在这里:
    ①首先构造了一个”implements Runnable “的无名local内部类(方法内的内部类) 
    ②然后构造了这个无名local内部类的一个实例 
    ③然后用Runnable来表示这个无名local内部类的type(OO多态)。
    例如上面这段代码编译后你会看到其实是编译了两个类来的,如下:

这里写图片描述

    其中Text2$1就是无名local内部内类,这个也就很好地解释了为什么在main()方法中new Runnable(){xxx}里面的调用main()方法中的变量的时候要用final关键字来修饰。
    上面只是借助new Runnable(){xxx}特例来说明接口在方法中new的机制,对其他接口同理可得。
### 如何正确实现 `Runnable` 接口 在 Java 中,通过实现 `Runnable` 接口可以定义线程的任务逻辑。以下是具体实现方式以及可能遇到的相关问题: #### 实现 `Runnable` 的基本结构 为了使某个类能够被线程执行,可以通过让该类实现 `Runnable` 接口并重写其 `run()` 方法来完成任务定义[^1]。 ```java class MyRunnable implements Runnable { @Override public void run() { System.out.println("Thread is running."); } } ``` 在此基础上,创建一个线程实例并将实现了 `Runnable` 的对象传递给它作为目标任务。 ```java public class Main { public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.start(); // 启动线程 } } ``` 上述代码展示了如何启动一个新的线程,并使其运行由 `MyRunnable` 定义的任务逻辑。 --- #### 可能的编码问题及其解决方案 当尝试实现 `Runnable` 接口时,可能会遇到一些常见错误或挑战: 1. **忘记调用 `start()` 方法** 如果仅创建了线程而未调用 `start()` 方法,则不会真正启动新线程。此时只会初始化线程对象而不触发任何并发行为。 2. **共享资源的竞争条件 (Race Condition)** 当多个线程操作同一变量且没有同步机制保护时,可能导致不可预测的结果。例如,在多线程环境下修改计数器值时可能出现丢失更新的情况。为此应考虑使用关键字 `synchronized` 或其他高级锁工具如 `ReentrantLock` 来保障一致性[^3]。 3. **异常处理不当** 在 `run()` 方法内部发生的未经捕获的异常会终止当前线程,因此建议始终围绕核心业务逻辑设置合适的 try-catch 块以增强健壮性。 4. **项目加载后的潜在报错情况** After opening the project, there may be an error reported when certain dependencies are missing or misconfigured within your build system such as Maven configuration files not properly set up leading to unresolved symbols during compilation time. 对于这些问题中的最后一项,确保所有必要的库已正确定义于项目的构建文件之中非常重要;比如采用 Apache Maven 构建工具时需检查 pom.xml 文件里是否声明了所需的外部依赖关系[^2]。 --- ### 示例:带参数化的 `Runnable` 实现 下面是一个稍微复杂的例子,展示了一个接受输入参数并通过构造函数赋值给成员字段后再供后续使用的自定义 `Runnable` 类型。 ```java class ParameterizedTask implements Runnable { private final String taskName; public ParameterizedTask(String name){ this.taskName = name; } @Override public void run(){ for(int i=0;i<5;i++) { System.out.printf("%s: Iteration %d\n",taskName,i); try{ Thread.sleep(100); // Simulate work delay. }catch(InterruptedException e){ Thread.currentThread().interrupt(); break; // Exit loop upon interruption request. } } } } // Usage Example: public class RunnerApp { public static void main(String[] args)throws InterruptedException{ Thread t1=new Thread(new ParameterizedTask("Task-A")); Thread t2=new Thread(new ParameterizedTask("Task-B")); t1.start();t2.start(); t1.join();t2.join();// Wait until both threads finish their jobs before exiting application. System.out.println("All tasks completed successfully!"); } } ``` 此程序片段演示了两个独立工作的线程分别打印自己的迭代次数直到结束为止的过程。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值