欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaSE-Runnable接口实现多线程

程序员文章站 2022-05-05 16:41:32
...

        因为Java中不支持类的多继承,所以在使用继承Thread类来实现多线程时,存在继承局限,所以Java中又提供了另一种多线程的实现模式:Runnable接口实现多线程

        首先看一下Runnable接口的源码

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

        然后我们来实现一个Runnable接口

class My_Runnable implements Runnable{
    @Override
    public void run() {
        System.out.println("My_Runanble的run方法");
    }
}

public class Main{
    public static void main(String[] args){
        Runnable New_Runnable = new My_Runnable();
        Thread thread = new Thread(New_Runnable);
        thread.start();
        System.out.println("运行结束");
    }
}

        实现了Runnable接口之后,我们应该将它作为Thread类的构造参数。Thread类的构造方法有八种。

Thread(); 分配新的Thread对象
Thread(String name); 分配新的Thread对象
Thread(Runnable target); 分配新的Thread对象
Thread(Runnable target, String name); 分配新的Thread对象
Thread(ThreadGroup group, Runnable target); 分配新的Thread对象
Thread(ThreadGroup group, Runnable target, String name); 分配新的Thread对象,将target作为其运行对象,将指定的name作为其名称,并作为group所引用的线程组的一员。
Thread(ThreadGroup group, String name); 分配新的Thread对象
Thread(ThreadGroup group, Runnable target, string name, long StackSize); 分配新的Thread对象,将target作为其运行对象,将指定的name作为其名称,并作为group所引用的线程组的一员,并具有指定的堆栈大小。

        在这8个构造方法中,有Thread(Runnable target)和Thread(Runnable target, String name)可以直接传递Runnable接口,就像上面的例子一样,上面的例子使用了Thread(Runnable target)构造方法。

        还有一点就是:Thread类也是实现了Runnable接口的类,所以在Thread类的构造中才可以接收Runnabe接口的对象。

        因为Runnable接口只含有一个抽象方法,是函数式接口,我们也可以用lamdba表达式来进行Runnable接口的对象创建。

public class Main{
    public static void main(String[] args){
        Runnable New_Runnable = () -> System.out.println("使用lamdba表达式创建的接口实现对象");
        Thread thread = new Thread(New_Runnable);
        thread.start();
        System.out.println("运行结束");
    }
}

        因为Runnable接口实现多线程可以避免Thread类实现多线程的继承局限性,所以Runnablea接口要更好一些,除此之外,这两种实现方式还有一些其他的区别。

        首先,我有在上面提过:Thread类也实现了Runnable接口,所以Thread的构造函数不仅可以传入Runnable接口的实现对象,也可以传入一个Thread类的对象,这样就可以把一个Thread的对象的交给其他的线程对象进行调用。

        其次,有关线程类的继承结构,使用了代理设计模式:对于Runnable接口,Thread类继承于它,我们使用的新线程也是Runnable接口的实现类,所以在这里Thread类是辅助实现的代理类(Proxy),而我们的新线程类(假设是My_Thread)是主业务的实现类。

class My_Runnablle implements Runnable{
    private int tacket = 10;

    @Override
    public void run() {
        while (tacket>0){
            System.out.println(Thread.currentThread().getName()+"还有"+this.tacket--+"张票");
        }
    }
}
public class Main{
    public static void main(String[] args){
        Runnable New_Runnable = new My_Runnablle();
        new Thread(New_Runnable,"新线程1").start();
        new Thread(New_Runnable,"新线程2").start();
    }
}

        Runnable接口实现多线程可以更好的描述资源共享的情形。例如这段代码的输出结果为。

JavaSE-Runnable接口实现多线程

        这就实现了两个线程共享一份资源的情况。

        对于Runnable接口实现多线程我就先总结到这里,后续可能会有补充。