美文网首页
多线程(2) — 线程的创建

多线程(2) — 线程的创建

作者: 烧杰 | 来源:发表于2018-04-17 22:20 被阅读0次

1.怎么开启线程,主要有两种方法继承Thread类与实现Runnable或者Callable接口,但其实Runnable与Callable很类似,只不过Callable里面定义了回调的返回值且可声明抛出异常而已。

三种创建线程方式对比:

image.png

在现实中一般推荐采用实现Runnable和Callable接口的方式来创建多线程,因为Java不支持子类多继承,所以当线程已经继承了Thread类就不能再继承其他父类了。

2.再看两个创建线程的例子:

public class ThreadTest {
    public static void main(String[] args) {
        Thread thread = new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("1: " + Thread.currentThread().getName());
                    System.out.println("2: " + this.currentThread().getName());
                }
            }
        };
        thread.start();

     Thread thread2 = new Thread(new Runnable() {
              @Override
              public void run() {
                  while (true){
                      try {
                          Thread.sleep(500);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      System.out.println("1: " + Thread.currentThread().getName());
                  }
              }
          });
          thread2.start();

    }
}

Thread thread = new Thread();本身就已经创建了线程,继承父类run方法:

    public void run() {
        if (target != null) {
            target.run();
        }
    }

可见Thread下的run方法仅仅是对线程做了个非空的判断,但这不是我们想要的方法,所以要覆盖父类的run方法,即如上代码所示在覆盖的run方法中写自己的代码。(如果sleep(毫秒)了就要try-catch)

再回到上面两种方法,第一个是new Thread 覆盖run方法,第二种是new的Runnable去写run方法。

问:Runnable不是接口吗,怎么能实例化new Runnable()了?

答:因为匿名内部类,在《Java核心技术卷1》253页的匿名内部类节中写道:“如果构造参数的闭小括号后面跟一个开大括号,正在定义的就是匿名内部类”。对于上面的new Runnable可以理解成:

class Anonymous implement Runnable(){
    @ Override
     public void run(){
      }
}
Runnable runnable = new Anonymous();

故实质并不是实例化接口。抽象类也是一样比如某些类abstrct Animal 本身就不应该设计成可以实例化因为“动物”是抽象的,只有具体的猫、狗才能实例化,否则没意义。
所以以下也是可以的,不过要覆盖所有接口实现的方法

image.png

问:为什么在第一种方法打印的时候可以用this第二种不可以。
答:this表示的是当前方法所指的对象,即run()所指的对象Thread,但第二种方this指的就是new Runnable(),指不到Thread故不能用。

相关文章

网友评论

      本文标题:多线程(2) — 线程的创建

      本文链接:https://www.haomeiwen.com/subject/unxaqftx.html