线程的创建有两种方式,昨天学习过其中的一种:
创建一个类,继承自Java里的Thread类,并重写run方法。
最后再创建自定义线程的对象,并调用start方法,这样就启动一个线程了。
那么Thread到底是个什么东西呢?
一、Thread类
在Java里面线程就是一个类,就叫Thread,无论是哪种创建方式,都是离不开它的,看看它有哪些常用方法:
①创建一个线程对象。
其中可以给线程初始化赋值名字,若是没有初始化,线程则使用默认名。
②getName方法:获取线程的名字。
③currentThread方法:获取当前所处的线程的对象。
这是一个静态方法,所以可以直接用类名调用该方法,现在是在main方法中,所以获取的就是主线程。
④获取当前所处线程的名字:也就是主线程的名字。
第一个线程名是我们自己创建的那个线程,也称之为子线程,它名字叫Thread-0;
第二个线程名是主线程的,它的名字是main。
主线程的名字是确定的,子线程的名字我们是可以初始化命名的。
如果没有初始化的话,那就是Thread-0、Thread-1、Thread-2这样依次增加。
⑤其中还有一个start方法:
这个方法昨天就接触过,当线程调用这个方法时,线程会启动,同时Java虚拟机会调用此线程的run方法。
start就相当于线程的启动开关,调用了这个方法,线程才能启动,同时run方法才能运行,不调用start方法,只调用run方法,它是没法运行的。
其实创建线程的方法除了这种,还有一个方式:实现Runnable接口创建线程。
①创建一个类:实现Java里的Runnable接口。
②重写该接口的run()方法
③创建实现类的对象
④创建thread对象:初始化赋值,将该实现类的对象初始化赋值给线程类。
⑤启动线程
这种创建方式和Thread的构造方法是有关的,其中Thread有四种构造方法:Thread():无参构造,创建一个线程对象。
Thread(String name):给线程对象指定一个名字。
Thread(Runnable target):分配一个指定的线程对象。
Thread(Runnable target,String name):分配一个指定的线程对象并指定名字。
也就是说,接口Runnable可以作为Thread的构造方法的参数,但是因为接口无法实例化创建对象,所以我们要先创建一个实现类实现接口Runnable,再作为参数给Thread。
这两种创建线程的方式,其实都有些复杂,毕竟都需要我们去创建一个新的类:
方法一:创建Thread的子类;
方法二:创建Rannable的实现类。
能不能简化呢?
是可以的,使用到匿名内部类就可以了。
二、回顾匿名内部类
对于许多零基础学Java的人来说,我想应该会遇到各种各样的坎。数组应该是第一个小坎,然后就是面向对象,接口,多态等……
其中匿名内部类这个概念相信会是很多人的一个坎,似懂非懂,弄得也不是很明白,但是这个概念又非常的重要。
今天我们就再回顾下什么叫匿名内部类:
①创建一个接口A(也可以是一个类A,都可以)
②newA(){}:这就是匿名内部类的定义格式。
③创建一个类B实现接口A,再创建B的对象。
什么叫匿名内部类?
②的本质就相当于③,③有两个步骤:一是创建类B实现接口A,二是创建该类的对象。
匿名内部类本质就是将这两个步骤合成一个步骤了,这样也更加地简洁。
所以匿名内部类匿的是什么?
匿的是类名,匿的是接口A的实现类B的类名。
不用再重新创建一个类了,但是因为我没有类名,就用我爸爸(父类或者父接口)的名字代替,这便是格式newA(){}的由来。这就是匿名内部类。
三、匿名内部类方式实现线程的创建
方式一:Thread的子类
这种方式我们需要创建一个自定义线程类MyThread,再继承Thread。
如果使用匿名内部类的话,就不需要再创建MyThread了,直接使用匿名内部类就好了。
上图左右两边是作用是一样的,并且显然,使用匿名内部类会更加地简洁。
同样的道理,第二种创建线程的方式也可以使用匿名内部类。
方式二:Runnable的实现类
这种方式我们需要创建Runnable的一个实现类。
如果使用匿名内部类的话,就不需要再创建该实现类了,直接使用匿名内部类。
总结: