1.创建子类,继承Thread,重写run方法
2.创建子类,实现Runnable接口,重写run方法
3.继承Thread,使用匿名内部类
4.实现Runnable,使用匿名内部类
5.lambda表达式(推荐)
继承Thraed重写run
步骤:继承->重写->实例->启动
缺点:线程和任务绑定在一起
java
//1.继承
class MyThread extends Thread{
//2.重写
@Override
public void run() {
while (true){
System.out.println("hello thread");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Demo1 {
public static void main(String[] args) throws InterruptedException {
//MyThread thread = new MyThread();
//3.实例
Thread thread = new MyThread();
//4.启动
thread.start();
while (true){
System.out.println("hello main");
Thread.sleep(2000);
}
}
}
实现Runnable重写run
步骤其实大差不差,区别在于,不仅要实例化Thread对象,还要实例化Runnable对象,将Runnable对象作为参数传给Thread
通俗一点来说就是,Runnable是单独描述线程要执行的任务的,此时与线程没关系,将其作为参数传给Thread就是告诉线程所要执行的任务是什么,两者之间解耦合度更高,而第一种方法是将线程和任务绑定在了一起,耦合度更高
java
class MyRunnable implements Runnable{
@Override
public void run() {
while (true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class Demo2 {
public static void main(String[] args) throws InterruptedException {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
while (true){
System.out.println("hello main");
Thread.sleep(1000);
}
}
}
3.继承Thread,使用匿名内部类
本质上跟第一种方法没区别,只不过使用了匿名内部类来创建线程,好处就在于这个类是一次性的,只使用一次,也就是跟着当前线程一起,线程结束,类也结束
java
public class Demo3 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(){
@Override
public void run() {
while (true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
};
t.start();//真正创建线程
while(true){
System.out.println("hello main");
Thread.sleep(1000);
}
}
}
4.实现Runnable,使用匿名内部类
java
public class Demo4 {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
});
t.start();
while (true){
System.out.println("hello main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
注意写法即可
5.lambda表达式
这是更推荐的一种做法,更加简洁
java
public class Demo5 {
public static void main(String[] args) {
//lambda
Thread thread = new Thread(()->{
while (true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
thread.start();
while (true){
System.out.println("hello main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
使用lambda表达式需要注意的是变量捕获的情况:final 事实final(没有被修改的变量)
问题:为什么在继承或实现Runnable的时并不需要导包呢?
是因为他们都属于lang包底下,在Java中,lang包会默认导入到项目中,因此不需要手动import
这是基于管理方便的缘故,用什么类就导入什么包,但也存在这种方便的,默认自动导入的lang包