05-案例实现
案例实现
根据如下步骤实现本案例。
1.创建一个名为 Calculator
的类,并实现 Runnable
接口:
public class Calculator implements Runnable {
2.实现 run()
方法。在这个方法中,存放着线程将要运行的指令。在这里,这个方法用来计算20000以内的奇数:
@Override
public void run() {
long current = 1L;
long max = 20000L;
long numPrimes = 0L;
System.out.printf("Thread '%s': START\n",
Thread.currentThread().getName());
while (current <= max) {
if (isPrime(current)) {
numPrimes++;
}
current++;
}
System.out.printf("Thread '%s': END. Number of Primes: %d\n",
Thread.currentThread().getName(), numPrimes);
}
3.实现 辅助 方法 isPrime()
。该方法用于判断一个数是否为奇数:
private boolean isPrime(long number) {
if (number <= 2) {
return true;
}
for (long i = 2; i < number; i++) {
if ((number % i) == 0) {
return false;
}
return true;
}
}
4.实现应用程序的主方法,创建包含 main()
方法的 Main
类:
public class Main {
public static void main(String[] args) {
5.首先,输出线程的最大值、最小值和默认优先级:
System.out.printf("Minimum Priority: %s\n",
Thread.MIN_PRIORITY);
System.out.printf("Normal Priority: %s\n",
Thread.NORM_PRIORITY);
System.out.printf("Maximun Priority: %s\n",
Thread.MAX_PRIORITY);
6.创建10个 Thread
对象,分别用来执行10个 Calculator
任务。再创建两个数组,用来保存 Thread
对象及其 State
对象。后续我们将用这些信息来查看线程的状态。这里将5个线程设置为最大优先级,另5个线程设置为最小优先级:
Thread threads[];
Thread.State status[];
threads = new Thread[10];
status = new Thread.State[10];
for (int i = 0; i < 10; i++) {
threads[i] = new Thread(new Calculator());
if ((i % 2) == 0) {
threads[i].setPriority(Thread.MAX_PRIORITY);
} else {
threads[i].setPriority(Thread.MIN_PRIORITY);
}
threads[i].setName("My Thread " + i);
}
7.接着将一些必要的信息保存到文件中,因此需要创建 try-with-resources
语句来管理文件。在这个代码块中,先将线程启动前的状态写入文件,然后启动线程:
try (FileWriter file = new FileWriter(".\\data\\log.txt");
PrintWriter pw = new PrintWriter(file);) {
for (int i = 0; i < 10; i++) {
pw.println("Main : Status of Thread " + i + " : " +
threads[i].getState());
status[i] = threads[i].getState();
}
for (int i = 0; i < 10; i++) {
threads[i].start();
}
8.等待线程运行结束。在1.6节中,我们将用 join()
方法来等待线程结束。本案例中,由于我们需要记录线程运行过程中状态的转变,因此不能使用 join()
方法来等待线程结束,而应使用如下代码:
boolean finish = false;
while (!finish) {
for (int i = 0; i < 10; i++) {
if (threads[i].getState() != status[i]) {
writeThreadInfo(pw, threads[i], status[i]);
status[i] = threads[i].getState();
}
}
finish = true;
for (int i = 0; i < 10; i++) {
finish = finish && (threads[i].getState() ==
State.TERMINATED);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
9.在上述代码中,我们通过调用 writeThreadInfo()
方法来将线程信息记录到文件中。代码如下:
private static void writeThreadInfo(PrintWriter pw,
Thread thread,
State state) {
pw.printf("Main : Id %d - %s\n", thread.getId(),
thread.getName());
pw.printf("Main : Priority: %d\n", thread.getPriority());
pw.printf("Main : Old State: %s\n", state);
pw.printf("Main : New State: %s\n", thread.getState());
pw.printf("Main : ************************************\n");
}
10.运行程序,然后观察不同的线程是如何同时运行的。