开启一个线程的方法:
- 继承 Threrad 重写 run方法,调用 start 开启线程
- 实现 Runnable 接口实现 run方法,创建 Thread 时作为参数传递并调用 start 开启线程
- 实现 Callable 接口
注意:线程是程序中执行的线程。 Java虚拟机允许应用程序同时执行多个执行线程。
小拓展:
每个线程都有优先权。 具有较高优先级的线程优先于优先级较低的线程执行(当然能不能先执行还得看CPU心情)。 每个线程可能也可能不会被标记为守护程序。 当在某个线程中运行的代码创建一个新的
Thread
对象时,新线程的优先级最初设置为等于创建线程的优先级,并且当且仅当创建线程是守护进程时才是守护线程。
Thread 实现了 Runnable 接口
继承 Threrad 重写 run方法,调用 start 开启线程
package mii.thread.demo01Thread;
/**
* 创建线程方式一:继承Thread类【备注:线程开启不一定立即执行,由CPU调度执行】
* 重写run()方法
* 调用start()开始线程
*/
public class TestThread extends Thread {
@Override
public void run() {
// run方法线程体
for (int i = 0; i < 10; i++) {
System.out.println("I'm looking code -- " + i);
}
}
/**
* main线程,主线程
* @param args
*/
public static void main(String[] args) {
/**
* 创建线程对象,调用start启动线程
* 【注:如果调用run方法则正常流水线式运行,只有调用start才会重新开启一个线程执行run方法】
*/
TestThread tt = new TestThread();
tt.start();
for (int i = 0; i < 10; i++) {
System.out.println("我在学习多线程 -- " + i);
}
}
}
第二种方法来创建一个线程是实现
Runnable
接口。 实现run
方法。 然后可以分配类的实例,在创建Thread
时作为参数传递,并启动。相对 Thread 的优点:避免了类单继承的局限性,Runnable 是函数式接口,可以使用 Lambda 表达式
package mii.thread.demo03Runnable;
/**
* 创建线程方式二:实现Runnable接口
* 实现run方法
* 执行线程需要将实现类对象丢入Thread,调用start启动线程
*/
public class TestRunnable implements Runnable{
@Override
public void run() {
// run方法线程体
for (int i = 0; i < 10; i++) {
System.out.println("I'm looking code -- " + i);
}
}
/**
* main线程,主线程
* @param args
*/
public static void main(String[] args) {
/**
* 创建Runnable实现类对象,将实现类对象丢入Thread调用start开启线程【代理】
*/
new Thread(new TestRunnable()).start();
// Lambda
new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("Lambda -- " + i);
}
}).start();
for (int i = 0; i < 10; i++) {
System.out.println("我在学习多线程 -- " + i);
}
}
}
- 实现 Callable 接口需要返回值类型
- 重写 call 方法
- 创建目标对象
- 创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(num)
- 提交执行
Future
result = ser.submit(thread) - 获取结果
boolean r = result.get()
- 关闭服务
ser.shutdownNow()
package mii.thread.demo07Callable;
import java.util.concurrent.*;
/**
* 线程创建方式三:实现Callable接口
* 好处:
* 1、可以定义返回值
* 2、可以抛出异常
*/
public class TestCallable02 implements Callable<Boolean> {
private String name;
public TestCallable02(String name) {
this.name = name;
}
@Override
public Boolean call() throws Exception {
for (int i = 0; i < 4; i++) {
System.out.println(name + " 数到了 " + i);
}
return true;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 1、创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
// 2、提交执行
Future<Boolean> result0 = ser.submit(new TestCallable02("A"));
Future<Boolean> result1 = ser.submit(new TestCallable02("B"));
Future<Boolean> result2 = ser.submit(new TestCallable02("C"));
// 3、获取结果
boolean r0 = result0.get();
boolean r1 = result1.get();
boolean r2 = result2.get();
System.out.println("r0=" + r0 + "\nr1=" + r1 + "\nr2=" + r2);
// 4、关闭服务
ser.shutdownNow();
}
}