Java 多线程练习

OOP h15

0x00 ThreadUtil

测试程序输入一个 StringBuffer,刚输入的时候 StringBuffer 值为空,等待1000 ms 后,这个 StringBuffer 的值变为 “ok”。

传入 StringBuffer 时不能赋值,1000 ms 后赋值完成,所以赋值需要在 0~1000 ms 内进行。

采用多线程的方式,继承 Thread 类,重写 run 方法,睡眠 100 ms 再赋值。需要声明 StringBuffer 类型成员变量,便于在 run 中赋值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.huawei.classroom.student.h15;

/**
* @author super
*/
public class ThreadUtil extends Thread {
private final StringBuffer buffer;
public ThreadUtil(StringBuffer buf) {
this.buffer = buf;
}

@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.buffer.append("ok");
}
}

0x01 PrimeUtil

多线程方式,统计 [start,end) 区间所有的质数,并且从小到大排序返回。

采用多线程的方式,所以应为单独一个线程创建类 PrimeThread

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
package com.huawei.classroom.student.h15;

import java.util.ArrayList;
import java.util.List;

/**
* @author super
*/
public class PrimeThread extends Thread {
private final long start;// 区间开始位置
private final long end;// 区间结束位置
// 构造方法赋值
public PrimeThread(long start, long end) {
this.start = start;
this.end = end;
}
// 找质数
public List<Long> getPrime() {
long i;
List<Long> result = new ArrayList<>();
for (i = this.start; i < this.end; i++) {
if (isPrime(i)) {
result.add(i);
}
}
return result;
}
// 判断质数
public boolean isPrime(long num) {
long i;
for (i = 2; i <= Math.sqrt(num); i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
}

回到 PrimeUtil,传入的参数 threadCount 指明了线程数,所以需要创建大小为 threadCountPrimeThread 类型数组,每个元素计算对应长度的值,创建对象、start 开始计算。

最终 join 到一起,addAll 得到结果。

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
package com.huawei.classroom.student.h15;

import java.util.ArrayList;
import java.util.List;

/**
* @author super
*/
public class PrimeUtil {
public PrimeUtil() {

}

public List<Long> getPrimeList(long start, long end, int threadCount) {
int i;
List<Long> result = new ArrayList<>();
PrimeThread[] threads = new PrimeThread[threadCount];
for (i = 0; i < threadCount; i++) {
long threadStart = start + (end - start) / threadCount * i;
long threadEnd = start + (end - start) / threadCount * (i + 1);
threads[i] = new PrimeThread(threadStart, threadEnd);
threads[i].start();
}
for (i = 0; i < threads.length; i++) {
try {
threads[i].join();
result.addAll(threads[i].getPrime());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return result;
}
}

上述方法错在哪里?(未 override run 方法)

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
package com.huawei.classroom.student.h15;

import java.util.ArrayList;
import java.util.List;

/**
* @author super
*
*/
public class PrimeThread extends Thread {
private final long start;
private final long end;
private List<Long> result = new ArrayList<>();
public PrimeThread(long start, long end) {
this.start = start;
this.end = end;
}

public List<Long> getPrime() {
return result;
}
public boolean isPrime(long num) {
long i;
for (i = 2; i <= Math.sqrt(num); i++) {
if (num % i == 0) {
return false;
}
}
return true;
}

@Override
public void run() {
long i;
for (i = this.start; i < this.end; i++) {
if (isPrime(i)) {
result.add(i);
}
}
}
}