线程创建方式2: 实现Runnable接口

线程创建方式2: 实现Runnable接口

大纲:

1. 线程的创建方式一:继承Thread1.1 步骤:
(1)创建一个继承于Thread类的子类
(2)重写Thread类的run()方法--->将此线程要执行的操作,声明在方法体中
(3)创建当前Thread的子类的对象
(4)通过对象调用start()方法
    start()方法作用:1.启动线程 2.调用当前线程的run()方法


1.2 例题:创建一个分线程1,用于遍历100以内的偶数
【拓展】 再创建一个分线程2,用于遍历100以内的偶数



2.线程的创建方式二:实现Runnable接口
2.1 步骤:
(1)创建一个实现Runnable接口的类
(2)实现接口中的Run() ---> 将此线程要执行的操作,声明在方法体中
(3)创建当前实现类的对象
(4)将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
(5Thread类的实例调用start()方法
     start()方法作用:1.启动线程 2.调用当前线程的run()方法


2.2 例题:创建分线程遍历100以内的偶数



3.对比两种方式?
    共同点:(1)启动线程,使用的都是Thread类中定义的start()2)创建的线程对象,都是Thread类或其子类的实例。


    不同点:一个是类的继承,一个是接口的实现。
        建议:建议使用实现Runnable接口的方式。
        Runnable方式的好处:(1)实现的方式,避免了类的单继承的局限性
                            (2)更适合处理有共享数据的问题
                            (3)实现了代码和数据的分离。


    联系:public class Thread implements Runnable(代理模式)

代码举例:

package thread.demo01.runnable;


/*
线程的创建方式二:实现Runnable接口
步骤:
(1)创建一个实现Runnable接口的类
(2)实现接口中的Run() ---> 将此线程要执行的操作,声明在方法体中
(3)创建当前实现类的对象
(4)将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
(5)Thread类的实例调用start():1.启动线程   2.调用当前线程的run()
 */

public class EvenNumberTest {
    public static void main(String[] args) {
//(3)创建当前实现类的对象
        EvenNumberPrint r1 = new EvenNumberPrint();
//(4)将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
        Thread t1 = new Thread(r1);
//(5)Thread类的实例调用start():1.启动线程   2.调用当前线程的run()
        t1.start();

        //main()方法对应的主线程执行的操作
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }

        /*
        拓展:再创建一个线程,遍历100以内的偶数
         */
        Thread t2 = new Thread(r1);
        t2.start();

    }
}

//(1)创建一个实现Runnable接口的类
class EvenNumberPrint implements Runnable{

//(2)实现接口中的Run() ---> 将此线程要执行的操作,声明在方法体中
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
}

练习:创建两个分线程,其中一个线程遍历100以内的偶数,另一个线程遍历100以内的奇数。

这里主要看方式3

package thread.demo01.exercise1;

public class PrintNumberTest {
    public static void main(String[] args) {    //main()主线程
        //方式1:
//        Even t1 = new Even();
//        Odd t2 = new Odd();
//        t1.start();
//        t2.start();

        //方式2:创建Thread类的匿名子类的匿名对象。
        new Thread(){   //偶数
            @Override
            public void run() {
                for (int i = 1; i <= 100; i++) {
                    if (i % 2 == 0){
                        System.out.println(Thread.currentThread().getName() + ": ---- " + i);
                    }
                }
            }
        }.start();

        new Thread(){   //奇数
            @Override
            public void run() {
                for (int i = 1; i <= 100; i++) {
                    if (i % 2 != 0){
                        System.out.println(Thread.currentThread().getName() + ": " + i);
                    }
                }
            }
        }.start();

        //方式3:使用实现Runnable接口的方式:提供了Runnable接口匿名实现类的匿名对象
        new Thread(new Runnable() {
            @Override
            public void run() { //100以内偶数
                for (int i = 1; i <= 100; i++) {
                    if (i % 2 == 0){
                        System.out.println(Thread.currentThread().getName() + ": ---- " + i);
                    }
                }
            }
        }).start();

        new Thread(new Runnable(){
            @Override
            public void run() {
                for(int i = 1; i <= 100; i++){
                    if (i % 2 != 0){
                        System.out.println(Thread.currentThread().getName() + ":" + i);
                    }
                }
            }
        }).start();

    }
}

class Even extends Thread{  //用于打印偶数
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ": ---- " + i);
            }
        }
    }
}

class Odd extends Thread{   //用于打印奇数
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            if (i % 2 != 0){
                System.out.println(Thread.currentThread().getName() + ": " + i);
            }
        }
    }
}

思考1:判断各自调用的是哪个run()?

package thread.demo01.exercise2;


/*
思考题:判断各自调用的是哪个run()?
 */
public class Exercise {
    public static void main(String[] args) {
        A a = new A();
        a.start();//(1)启动线程 (2)调用Thread类的run()  输出:线程A的run()...

        B b = new B(a);
        b.start();//输出:线程B的run()...
        //start():导致此线程开始执行; Java虚拟机调用此线程的run方法。

    }
}

//创建线程类A
class A extends Thread{
    @Override
    public void run() {
        System.out.println("线程A的run()...");
    }
}

//创建线程类B
class B extends Thread{

    private A a;

    public B(A a) { //构造器中,之间传入A类对象
        this.a = a;
    }

    @Override
    public void run() {
        System.out.println("线程B的run()...");
    }
}

思考2:

package thread.demo01.exercise2;

public class Exercise_1 {
    public static void main(String[] args) {
        BB b = new BB();
        new Thread(b){
            @Override
            public void run() {
                System.out.println("CC的run()...");
            }
        }.start();//CC的run()...

        //new Thread(){}.start(); //什么都没有
}
}

class AA extends Thread{
    @Override
    public void run() {
        System.out.println("AA的run()...");
    }
}

class BB implements Runnable{
    @Override
    public void run() {
        System.out.println("BB的run()...");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值