Thread和Runnable的区别与匿名内部类方式实现线程的创建

Thread和Runnable的区别

如果非要说区别的话,那么就有一下几点

Runnable 和 Thread 创建线程的方式不一样

Runnable 是接口,Thread 是实体类,Thread 和 Runnable 的关系就是实体与实现的关系。

在使用上,如果有复杂的线程操作需求,那就选择继承Thread,如果只是简单的执行一个任务,那就实现Runnable 。

只有一个简单的 run(); 方法;
这个 run 不仅能 run 线程,还有其他东西也能 run(这个是目前的理解,至于其他东西是什么,我也无法举例)
而设置 Runnable 接口的目的就在于:Java 中只能实现单继承,而可以实现多个接口。如果某个类想 run,还行实现其他的,那么就可以通过实现 Runnable 接口完成 run,再实现其他接口或者继承其他类完成 多功能。

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。总结:
实现Runnable接口比继承Thread类所具有的优势:1.适合多个相同的程序代码的线程去共享同一个资源。2.可以避免java中的单继承的局限性。
3.增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。4.线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。
扩充∶在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个VM,每一个VM其实在就是在操作系统中启动了一个进程。

如果通过 Runnable 接口创建一个线程,那么应该是这样

class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println("实现 Runnable 节后后创建线程");
    }
}

public class Test{
    
    // 方法 1 : 通过继承 Runnable 创建线程
    public static void main1(String[] args) {
        // 向上转型 父类引用指向子类对象
        Runnable myThread = new MyThread ();
        
        Thread thread = new Thread(myThread);
        thread.start();
    }


    // 方法 2 : 通过 Runnable 匿名内部类创建线程
    public static void main2(String[] args) {
       Thread thread = new Thread(new Runnable() {
           @Override
           public void run() {
               System.out.println("Runnable 匿名内部类创建线程");
           }
       });
       thread.start();
   }

}

通过继承 Thread 创建线程

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("继承 Thread 接口创建线程");
    }
}

public class TestDemo2 {
    // 方法 1 : 继承 Thread 类创建线程
    public static void main1(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
    
    // 方法 2 : 匿名内部类创建线程
    public static void main2(String[] args) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("Thread 匿名内部类创建线程");
            }
        };
        thread.start();
    }

}

 

package Demo01_Sleep;

/*
    创建多线程程序的第二种方式:实现RunnabLe接口java.Lang. RunnabLe
        Runnable接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为 run的无参数方法。
    java.Lang.Thread类的构造方法
        Thread ( Runnable target)分配新的Thread对象。
        Thread ( Runnable target, string name)分配新的Thread对象。
    实现步骤:
        1.创隍一个Runnable接口的实现类
        2.在实现类中重写Runnable接口的run方法,设置线程任务
        3.创建一个Runnable接口的实现类对象
        4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
        5.调用Thread类中的start方法,开启新的线程执行run方法

        实现RunnabLe接口创建多线程程序的好处:
1.避免了单继承的局限性
一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类实现了Runnable接口,还可以继承其他的类,实现其他的接口
2.增强了程序的扩展性,降低了程序的耦合性(解耦)
实现Runnabte接口的方式,把设置线程任务和开启新线程进行了分离(解耦)实现类中,重写了run方法:用来设置线程任务
创建Thread类对象,调用start方法:用来开启线程

 */

public class Demo01_Runnble01 {
    public static void main(String[] args) {
        //3.创建一个Runnable接口的实现类对象
        Demo01_Runnble runnble = new Demo01_Runnble();
        //4.创建Thread类对象,构造方法中传递Runnable接口的实现类对象
        Thread thread = new Thread(runnble);
        //5.调用Thread类中的start方法,开启新的线程执行run方法
        thread.start();
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName()+"-->"+i);

        }
    }
}

 

package Demo01_Sleep;
///1.创建一个Runnable接口的实现类
public class Demo01_Runnble implements Runnable {
    //在实现类中重写RunnabLe接口的run方法,设置线程任务
    public static void main(String[] args) {
    }
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("HelloWorld"+i);
        }
    }
}

 

匿名内部类方式实现线程的创建

使用线程的内匿名内部类方式,可以方便的实现每个线程执行不同的线程任务操作。

使用匿名内部类的方式实现Runnable接口,重新Runnable接口中的run方法∶

package Demo01_Sleep;
/*
匿名内部类方式实现线程的创建匿名:没有名字
内部类:写在其他类内部的类
匿名内部类作用:简化代码
把子类继承父类,重写父类的方法,创建子类对象合一步完成
把实现类实现类接口,重写接口中的方法,创建实现类对象合成—步匿名内部类的最终产物:子类/实现类对象,而这个类没有名字
格式:
    new父类/接口(){
        重复父类/接口中的方法
}
 */
public class Demo01InnerClassThread {
    public static void main(String[] args) {
        //线程的父类是Thread
        //new MyThread.start;
        new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+"-->"+"黑马");
                }
            }
        }.start();
        //线程的接口Runnable
        // Runnable r = neww RunnabLeImpL( );//多态
       Runnable  tr=  new Runnable(){
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+"-->"+"程序员");
                }
            }
        };
        new Thread(tr).start();
        //简化接口的方式
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 20; i++) {
                    System.out.println(Thread.currentThread().getName()+"-->"+"传智博客");
                }
            }
        }).start();
    }

}

 

posted @ 2022-07-07 20:53  zj勇敢飞,xx永相随  阅读(270)  评论(0编辑  收藏  举报