当前位置:嗨网首页>书籍在线阅读

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.运行程序,然后观察不同的线程是如何同时运行的。