2.创建线程方式
创建线程的三种方式
- 继承Thread类,重写run()方法。
- 实现Runnable接口,实现run()方法。(推荐使用,因为java单继承的局限性)
- 实现Callable接口,实现call()方法。
- 通过线程池创建。
1.Thread
- 自定义线程类 继承Thread类
- 重写 run() 方法,编写线程执行体
- 创建线程对象,调用 start() 方法来启动线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24// 创建线程
public class TestThread extends Thread{
// run方法线程体
public void run(){
for (int i = 0; i < 20; i++) {
System.out.println("run方法线程体" + i);
}
}
}
// 测试类
class Test{
// main方法 主线程
public static void main(String[] args) {
// 调用写好的线程
TestThread testThread = new TestThread();
testThread.start();
for (int i = 0; i < 500; i++) {
System.out.println("main方法 主线程" + i);
}
}
}
结果:
1 | run方法线程体11 |
2.实现Runnable
- 定义MyRunnable类 实现 Runnable接口
- 实现 run()方法 ,编写线程执行体
- 创建线程对象,调用 start()方法
- Runnable接口源码(函数式接口,可用lambda表达式)
1
2
3
4
public interface Runnable {
public abstract void run();
}
简单测试:
1 | // 实现Runnable,实现run()方法 |
2.1:实现Runnable接口的方式,避免了单继承的局限性,方便同一个对象被多个线程使用。
1 | // 一份资源 |
举例1:模拟买火车票例子。
1 | public class MyRunnable implements Runnable{ |
结果:同一张票被多人抢到 (多线程操作同一资源的情况下,线程不安全,数据紊乱)
1 | 李四:获得了第6张票 |
举例2:模拟龟兔赛跑
1 | // 模拟龟兔赛跑(谁先跑到100步谁胜利) |
结果:
1 | 兔子跑了:9步 |
3.Callable
- 实现Callable接口,需要返回值类型。
- 重写call()方法,需要抛出异常
- 创建目标对象
- 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(2);
- 提交执行:Future
resul1 = ser.submit(t1); - 获取结果:boolean r1 = resul1.get();
- 关闭服务:ser.shutdownNow();
例:
1 | public class TestCallable implements Callable<Boolean> { |