文章目录
一、继承Thread类
子类可以继承Thread类,重写Thread类的run()方法从而创建线程
public class Thread1 extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行了~~~");
}
public static void main(String[] args) {
Thread1 thread1=new Thread1();
thread1.start();
}
}
这种方式直接创建子类的实例化对象,调用start()方法既可启动线程
二、实现Runnable接口
子类实现Runnable接口,重写run()方法,这里实际上还是重写的Thread类的run()方法
/**
* @author :xuezhiqian
* @description:TODO:实现Runnable接口
* @date :2022/8/1 9:47
*/
public class Thread2 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行了~~~~~");
}
public static void main(String[] args) {
//需要创建一个Thread对象,将实现了Runnable接口类的对象传进去
Thread thread=new Thread(new Thread2());
thread.start();
}
}
也可以使用匿名内部类创建线程
Thread thread=new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 执行了~~~");
}
},"匿名内部类线程");
thread.start();
同时这种只有一个抽象方法的接口,可以使用Lambda表达式
Thread thread2=new Thread(()->{
System.out.println("Lambda表达式");
});
thread2.start();
三、实现Callable接口
实现Callable接口,重写它的call()方法
注意:
Callable接口是有返回值的,要获取他的返回值,需要结合FutureTask
/**
* @author :xuezhiqian
* @description:TODO:实现Callable<E>接口
* 这是一个有返回值的
* @date :2022/8/1 9:52
*/
public class Thread3 implements Callable<Integer>{
//重写call方法
@Override
public Integer call() throws Exception {
Integer result=10;
System.out.println(Thread.currentThread().getName()+"Callable接口执行了~~~ " );
return result;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//需要使用FutureTask<E>包装实现了Callable接口类的实例化对象
FutureTask<Integer> task=new FutureTask<>(new Thread3());
Thread thread=new Thread(task);
thread.start();
//获取返回值需要调用FutureTask的get()方法
Integer result=task.get();
System.out.println(result);
}
}
四、创建定时器线程
public class TimmerThread {
public static void main(String[] args) {
Timer timer=new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("定时器线程执行了~~~");
}
},3000,3000);
//delay:延迟多久开始执行(例如这个代码就是延迟三秒开始执行第一次);
//period:执行周期,就是隔多久执行一次
}
}
补充:
直接调用run()方法和调用start()方法有什么区别?
我们的目的是创建一个子线程去执行run()方法中的内容,主线程继续向下执行。
而直接在主进程中调用run(),就相当于调用了一个普通方法,主程序会进入run()方法,执行完毕后退出run()方法继续执行主方法,就没有新线程的产生。而调用start()方法,会产生一个新的线程,主线程不会进入run()方法,run()方法的执行交由新线程去执行,主线程继续向下顺序执行。