实践-java线程示例

使用java运行多线程示例。

实现java.lang.Runnable接口

  • 为了使类可运行,我们可以实现java.lang.Runnable接口并在public void run()方法中提供实现。要将此类用作Thread,我们需要通过传递此runnable类的对象来创建Thread对象,然后调用start()方法运行。
1
2
3
4
5
6
7
8
9
10
11
12
package cn.z201.java.test.thread;

/**
* @author z201.coding@gmail.com
**/
public class RunnableExample implements Runnable {

@Override
public void run() {
System.out.println("RunnableExample currentThread tid: " + Thread.currentThread().getId());
}
}
  • 运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package cn.z201.java.test.thread;

/**
* @author z201.coding@gmail.com
**/
public class ThreadMain {

public static void main(String[] args) {

Thread thread = new Thread(new RunnableExample());
thread.start();
}

}
>> RunnableExample currentThread tid: 11

扩展java.lang.Thread类

  • 扩展java.lang.Thread类来创建我们自己的java线程类和覆盖run()方法。然后我们可以创建它的对象和调用start()方法来执行我们的自定义java线程类run方法。
1
2
3
4
5
6
7
8
9
10
11
12
package cn.z201.java.test.thread;

/**
* @author z201.coding@gmail.com
**/
public class ThreadExample extends Thread {

@Override
public void run() {
System.out.println("ThreadExample currentThread tid: " + Thread.currentThread().getId());
}
}
  • 运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package cn.z201.java.test.thread;

/**
* @author z201.coding@gmail.com
**/
public class ThreadMain {

public static void main(String[] args) {
ThreadExample threadExample = new ThreadExample();
threadExample.start();

//Thread thread = new Thread(new RunnableExample());
//thread.start();
}
}
>> ThreadExample currentThread tid: 11

Runnable VS Thread

  • 实现Runnable是首选,因为java支持实现多个接口。如果扩展Thread类,则不能扩展任何其他类。

  • 扩展Thread的类可能只是需要运行,继承整个Thread类开销过大。

实现java.util.concurrent.Callable使用FutureTask启动。

  • 实现callable接口,并实现call方法。可以获得call方法的返回值。
  • Callable任务返回java.util.concurrent.Future对象。使用Java Future对象,我们可以找出Callable任务的状态并获取返回的Object。它提供了get()方法,可以等待Callable完成然后返回结果。
  • Java Future提供cancel()方法来取消关联的Callable任务。有一个重载的get()方法,我们可以指定等待结果的时间,避免当前线程被阻塞更长时间是有用的。有isDone()isCancelled()方法来查找关联的Callable任务的当前状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package cn.z201.java.test.thread;

import java.util.concurrent.Callable;

public class CallableExample implements Callable<Integer> {

@Override
public Integer call() throws Exception {
int result = 0;
for (int i = 0 ; i < 10 ; i++) {
System.out.println(Thread.currentThread().getName() + " --- " + i);
result = i;
}
return result;
}
}
  • 运行结果
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
package cn.z201.java.test.thread;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
* @author z201.coding@gmail.com
**/
public class ThreadMain {

public static void main(String[] args) {

CallableExample ctt = new CallableExample();
FutureTask ft = new FutureTask<Integer>(ctt);
for (int i = 0 ; i < 10 ; i++) {
System.out.println(Thread.currentThread().getName() + " 的循环变量i的值" + i);
if (i == 5) {
new Thread(ft , "有返回值的线程").start();
}
}
try {
System.out.println("子线程的返回值:" + ft.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}

}
>>
main 的循环变量i的值0
main 的循环变量i的值1
main 的循环变量i的值2
main 的循环变量i的值3
main 的循环变量i的值4
main 的循环变量i的值5
main 的循环变量i的值6
main 的循环变量i的值7
main 的循环变量i的值8
main 的循环变量i的值9
有返回值的线程 --- 0
有返回值的线程 --- 1
有返回值的线程 --- 2
有返回值的线程 --- 3
有返回值的线程 --- 4
有返回值的线程 --- 5
有返回值的线程 --- 6
有返回值的线程 --- 7
有返回值的线程 --- 8
有返回值的线程 --- 9
子线程的返回值:9