版权声明:作者:N3verL4nd 出处: https://blog.csdn.net/lgh1992314/article/details/79778575
继承 Thread 类
定义 Thread 类的子类,并重写该类的run()
方法,该run()
方法的方法体就代表了该线程要完成的任务。因此把run()
方法称为执行体。本质上讲,run()
就是我们自定义的回调函数,既然是回调函数,我们直接调用它就没有任何意义了~
然后创建 Thread 子类的实例,即创建了线程对象。调用线程对象的start()
方法来启动该线程。
class MyThread extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " starts...");
}
}
public class Main {
public static void main(String[] args) {
Thread thread = new MyThread();
thread.start();
}
}
Thread.currentThread()
方法返回当前正在执行该方法执行的线程对象。
getName()
方法返回该线程的名称
实现 Runnable 接口
定义java.lang.Runnable
接口的实现类,并重写该接口的run()
方法,该run()
方法的方法体同样是该线程的线程执行体。
package java.lang;
@FunctionalInterface // 支持函数式调用
public interface Runnable {
public abstract void run();
}
// 作为线程的任务而存在
class MyRunnable implements java.lang.Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " starts...");
}
}
public class Main {
public static void main(String[] args) {
new Thread(new MyRunnable(), "first thread").start();
new Thread(new MyRunnable(), "second thread").start();
}
}
我们来看看它是如何实现的:
//
private Runnable target;
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
@Override
public void run() {
if (target != null) {
target.run();
}
}
匿名内部类的方式
public class Main {
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " starts...");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " starts...");
}
}).start();
}
}
对于以下代码,输出结果是什么呢?
public class Main {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Runnable::run");
}
}) {
@Override
public void run() {
System.out.println("Thread::run");
}
}.start();
}
}
输出结果为Thread::run
。
因为我们已经覆盖了Thread.run()
方法(子类覆盖父类的方法)–> 多态。
通过 Callable 和 Future 创建线程
- 创建 Callable 接口的实现类,并实现
call()
方法,该call()
方法将作为线程执行体,并且有返回值。 - 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的
call()
方法的返回值。 - 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
- 调用 FutureTask 对象的
get()
方法来获得子线程执行结束后的返回值
package test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName() + " starts...");
return "Hello World";
}
}
public class Main {
public static void main(String[] args) {
FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
Thread thread = new Thread(futureTask);
thread.start();
try {
// 获取线程返回值
String val = futureTask.get();
System.out.println("返回值: " + val);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
定时器实现
import java.util.Timer;
import java.util.TimerTask;
public class Main {
public static void main(String[] args) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("hi");
}
}, 0, 1000);
}
}
更强大的控制可以使用 quartz
。
使用线程池
package test;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) {
Executor executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
((ExecutorService) executor).shutdown();
}
}
参考:
https://blog.csdn.net/longshengguoji/article/details/41126119