JAVA线程-线程的创建方式

本文最后更新于:April 15, 2022 am

积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里,不积小流无以成江海。齐骥一跃,不能十步,驽马十驾,功不在舍。面对悬崖峭壁,一百年也看不出一条裂缝来,但用斧凿,能进一寸进一寸,能进一尺进一尺,不断积累,飞跃必来,突破随之。

目录

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
25
26
package StudyMainThread;

/**
* @Author DragonOne
* @Date 2022/1/9 21:33
* @墨水记忆 www.tothefor.com
*/
public class StudyThread extends Thread{
@Override
public void run() {
for (int i=0;i<20;++i){
System.out.println("这是二线程"+i);
}
}

public static void main(String[] args) {

StudyThread st = new StudyThread();
// st.run();
st.start();

for (int i=0;i<20;++i){
System.out.println("这是主线程"+i);
}
}
}

📢提示:调用类StudyThread的start()方法和run()方法是有区别的。调用run()是顺序执行,而调用start()才是启动线程。具体可多次输出查看输出结果,看输出的顺序。

Runnable接口(推荐)

用一个自定义类实现Runnable接口。重写run()方法,创建线程对象(Thread)调用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
25
26
27
28
package StudyMainThread;

/**
* @Author DragonOne
* @Date 2022/1/9 22:06
* @墨水记忆 www.tothefor.com
*/
public class RunnableTest implements Runnable{
@Override
public void run() {
for (int i=0;i<20;++i){
System.out.println("这是二线程"+i);
}
}

public static void main(String[] args) {

RunnableTest rt = new RunnableTest();
//代理,可以简写为:new Thread(rt).start();
Thread th = new Thread(rt);
th.start();

for (int i=0;i<20;++i){
System.out.println("这是主线程"+i);
}
}
}

使用Runnable接口的好处是:避免了单继承的局限性(Thread类),灵活方便,方便同一个对象被多个线程使用。

Callable接口(了解)

实现Callable接口。

  1. 实现Callable接口,需要返回值类型。
  1. 重新call()方法,需要抛出异常。
  1. 创建目标对象。
  1. 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1); //1为线程数。
  1. 提交执行:Future<Boolean> result1 = ser.submit(t1);
  1. 获取结果:boolean r1 = result1.get();
  1. 关闭服务:ser.shutdownNow();

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package StudyMainThread;

import java.util.concurrent.*;

/**
* @Author DragonOne
* @Date 2022/1/9 22:39
* @墨水记忆 www.tothefor.com
*/
public class callableTest implements Callable<Boolean> {
private String name;
public callableTest(String name){
this.name = name;
}
@Override
public Boolean call(){
for (int i=0;i<20;++i){
System.out.println(name+"-->"+Thread.currentThread().getName()+"-->这是二线程"+i);
}
return true;
}

public static void main(String[] args) throws Exception{

callableTest ct1 = new callableTest("张三");
callableTest ct2 = new callableTest("李四");
callableTest ct3 = new callableTest("王五");
//创建执行服务:
ExecutorService ser = Executors.newFixedThreadPool(3);//线程池中的线程数设值

//提交执行:
Future<Boolean> result1 = ser.submit(ct1);
Future<Boolean> result2 = ser.submit(ct2);
Future<Boolean> result3 = ser.submit(ct3);

//获取结果:
boolean r1 = result1.get();
boolean r2 = result2.get();
boolean r3 = result3.get();

System.out.println(r1);
System.out.println(r2);
System.out.println(r3);
//关闭服务:
ser.shutdownNow();
}
}

//输出(部分结果)
王五-->pool-1-thread-3-->这是二线程2
张三-->pool-1-thread-1-->这是二线程6
张三-->pool-1-thread-1-->这是二线程7
王五-->pool-1-thread-3-->这是二线程3
李四-->pool-1-thread-2-->这是二线程1
李四-->pool-1-thread-2-->这是二线程2
李四-->pool-1-thread-2-->这是二线程3
王五-->pool-1-thread-3-->这是二线程4
张三-->pool-1-thread-1-->这是二线程8
王五-->pool-1-thread-3-->这是二线程5
王五-->pool-1-thread-3-->这是二线程6