併發

一、定義任務

public class LiftOff implements Runnable {

  protected int countDown = 10;
  private static int taskCount = 0;

  /**
   * 標識符ID可以用來區分任務的多個實例,final表示一旦被初始化之後就不希望被修改
   */
  private final int id = taskCount++;

  public LiftOff() {
  }

  public LiftOff(int countDown) {
    this.countDown = countDown;
  }

  public String status() {
    return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff!") + "). ";
  }

  public void run() {
    while (countDown-- > 0) {
      System.out.print(status());
      Thread.yield();
    }
  }
}

 

public class MainThread {
    public static void main(String[] args) {
        LiftOff launch = new LiftOff();
        launch.run();
    }
}

二、Thread類

public class MoreBasicThreads {
  public static void main(String[] args) {
    for (int i=0; i<5; i++) {
      new Thread(new LiftOff()).start();
    }
    System.out.println("Waiting for LiftOff");
  }
}

三、使用Executor

java.util.concurrent包中的執行器(Executor)管理Thread對象,從而簡化了併發編程。

public class CachedThreadPool {
  public static void main(String[] args) {
    ExecutorService exec = Executors.newCachedThreadPool();
    for (int i =0; i < 5; i++) {
      exec.execute(new LiftOff());
    }
    exec.shutdown();
  }
}

shutdown()方法的調用可以防止新任務被提交給這個Executor.

CachedThreadPool:爲每個任務都創建一個線程。

FixedThreadPool:使用有限的線程執行多個任務。

SingleThreadExecutor:使用一個線程執行多個任務。

四、從任務中產生返回值

Runnable是執行工作的獨立任務,但是它不返回任何值。如果希望在任務完成時能夠返回一個值,那麼可以實現Callable接口而不是Runnable接口。並且必須使用ExecutorService.submit()方法調用它:

 

import java.util.concurrent.Callable;

public class TaskWithResult implements Callable<String> {
  private int id;
  public TaskWithResult(int id) {
    this.id = id;
  }
  @Override
  public String call() {
    return "result of TaskWithResult " + id;
  }
}
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableDemo {
  public static void main(String[] args) {
    ExecutorService exec = Executors.newCachedThreadPool();
    ArrayList<Future<String>> results = new ArrayList<Future<String>>();
    for (int i = 0; i < 10; i++) {
      results.add(exec.submit(new TaskWithResult(i)));
    }
    for (Future<String> fs : results) {
      try {
        System.out.println(fs.get());
      } catch (InterruptedException e) {
        System.out.println(e);
        return;
      } catch (ExecutionException e) {
        System.out.println(e);
      } finally {
        exec.shutdown();
      }
    }
  }
}

submit方法會產生Future對象,它用callable返回結果的特定類型進行了參數化。用isDone()方法來查詢Future是否已經完成。當任務完成時,它具有一個結果,你可以調用get()方法來獲取該結果。當不用isDone進行檢查就直接調用get(),在這種情況下,get()講阻塞,直到結果準備就緒。

五、休眠

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class SleepingTask extends LiftOff {

  public void run() {
    try {
      while (countDown-- > 0) {
        System.out.print(status());
        TimeUnit.MICROSECONDS.sleep(10000);
      }
    } catch (InterruptedException e) {
      System.out.println("Interrupted");
    }
  }

  public static void main(String[] args) {
    ExecutorService exec = Executors.newCachedThreadPool();
    for (int i = 0; i < 5; i++) {
      exec.execute(new SleepingTask());
    }
    exec.shutdown();
  }
}

六、優先級

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SimplePriorites implements Runnable {
  private int countDown = 5;
  private volatile double d;
  private int priority;

  public SimplePriorites(int priority) {
    this.priority = priority;
  }

  public String toString() {
    return Thread.currentThread() + ": " + countDown;
  }

  @Override
  public void run() {
    Thread.currentThread().setPriority(priority);
    while (true) {
      for (int i = 1; i < 10000; i++) {
        d += (Math.PI + Math.E) / (double) i;
        if (i % 2 == 0) {
          Thread.yield();
        }
        System.out.println(this);
        if (--countDown ==0){
          return;
        }
      }
    }
  }

  public static void main(String[] args) {
    ExecutorService exec = Executors.newCachedThreadPool();
    for (int i = 0; i < 5; i++) {
      exec.execute(new SimplePriorites(Thread.MIN_PRIORITY));
    }
    exec.execute(new SimplePriorites(Thread.MAX_PRIORITY));
    exec.shutdown();
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章