1、继承Thread类
继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。该方法尽管被列为一种多线程实现方式,但是本质上也是实现了 Runnable 接口的一个实例。
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
//4.创建Thread类的子类对象
MyThread mt = new MyThread();
//5.开启线程
mt.setName("多线程");
mt.start();
for(int i = 0; i < 2; i++) {
System.out.println(Thread.currentThread().getName() + i);
// 让线程睡眠一会
Thread.sleep(10);
}
}
}
// 1.继承Thread
class MyThread extends Thread {
// 2.重写run方法
@Override
public void run() {
//3.将要执行的代码写在run方法中
for(int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
}
}
// 通过匿名类创建
public class ThreadTest {
public static void main(String[] args) {
//重写run方法,将要执行的代码写在run方法中
new Thread(() -> {
for (int i = 0; i < 4; i++) {
System.out.println("thread");
}
}).start();
}
}
2、实现Runnable接口
为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下:
public void run()
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
//4,创建Runnable的子类对象
MyRunnable mr = new MyRunnable();
//5,将其当作参数传递给Thread的构造函数
Thread t = new Thread(mr,"myrunnable");
t.start();
for(int i = 0; i < 2; i++) {
System.out.println(Thread.currentThread().getName() + i);
// 让线程睡眠一会
Thread.sleep(10);
}
}
}
//1,定义一个类实现Runnable
class MyRunnable implements Runnable {
// 2.重写run方法
@Override
public void run() {
//3.将要执行的代码写在run方法中
for(int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
}
}
// 内部匿名类
public class ThreadTest {
public static void main(String[] args) {
//1,将Runnable的子类对象传递给Thread的构造方法
new Thread(new Runnable() {
@Override
//2,重写run方法
public void run() {
//3,将要执行的代码写在run方法中
for(int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
}//4,开启线程
}).start();
}
}
3、通过 Callable 和 Future 创建线程
- 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
- 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
- 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
- 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
public class ThreadTest {
public static void main(String[] args) throws Exception{
MyCallable mc = new MyCallable(100);
FutureTask<Integer> f = new FutureTask<>(mc);
new Thread(f).start();
System.out.println(f.get());
}
}
class MyCallable implements Callable<Integer> {
private int number;
//实现从1加到100并返回结果
public MyCallable(int number) {
this.number = number;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for (int x = 1; x <= number; x++) {
sum += x;
}
return sum;
}
}
4、创建线程的三种方法对比
- 采用实现 Runnable、Callable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。
- 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。
5、线程池
Java中创建和销毁一个线程是比较昂贵的操作,需要系统调用。频繁创建和销毁线程会影响系统性能。于是线程池应运而生。其好处是可以抛出异常和有返回值。
- 创建线程池对象
- 创建Runnable实例
- 提交Runnable实例
- 关闭线程池
// 提交Runnable
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(2);
// 可以执行Runnable对象或者Callable对象代表的线程
pool.submit(new MyRunnable());
pool.submit(new MyRunnable());
//结束线程池
pool.shutdown();
}
}
//1,定义一个类实现Runnable
class MyRunnable implements Runnable {
// 2.重写run方法
@Override
public void run() {
//3.将要执行的代码写在run方法中
for(int i = 0; i < 4; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
}
}
//提交Callable
public class ThreadTest {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 创建线程池对象
ExecutorService pool = Executors.newFixedThreadPool(2);
// 可以执行Runnable对象或者Callable对象代表的线程
Future<Integer> f1 = pool.submit(new MyCallable(100));
Future<Integer> f2 = pool.submit(new MyCallable(200));
// V get()
Integer i1 = f1.get();
Integer i2 = f2.get();
System.out.println(i1);
System.out.println(i2);
// 结束
pool.shutdown();
}
}
class MyCallable implements Callable<Integer> {
private int number;
//实现从1加到100并返回结果
public MyCallable(int number) {
this.number = number;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for (int x = 1; x <= number; x++) {
sum += x;
}
return sum;
}
}
参考文章:
https://www.runoob.com/java/java-multithreading.html
https://blog.csdn.net/qq_40298054/article/details/87870297