并发学习一


基本概念

  • Java的线程机制是抢占式的。调度机制会周期的中断线程,将上下文切换到另外一个线程, 从而为每个线程都提供时间片,使得每个线程都会分配到数量合理的时间去驱动它的任务。
  • 线程状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING(超时等待)、TERMINATED。
  • 阻塞(BLOCKED): 程序中的某个任务因为该程序之外的某些条件导致不能继续执行。
  • 定义一个线程任务:实现Runable接口里面的run(),它是一个普通方法,要实现线程行为你需要new一个Thread通过start()来初始化线程最终run()才产生线程能力。还可实现Callable接口的call()
  • 使用执行器(java.util.concurrent.Executor)管理Thread对象。
    // 创建线程池 线程数与所需数量相同
    ExecutorService executorService = Executors.newCachedThreadPool();
    // 创建一个有大小限制的线程池
    ExecutorService exec = Executors.newFixdThreadPool(5);
    // 创建单线程池(创建线程数为1的FixedThreadPool)
    ExecutorService exec = Executors.newSingleThreadExecutor();
    
  • 休眠。调用sleep()方法抛出InterruptedException异常。
  • 让步。调用Thread里面的yield()方法。
  • 将线程转化为后台线程。调用Thread里面的setDaemon(true)方法。
  • 优先级, 在Thread类中定义了线程的三种优先级:
      public static final int MIN_PRIORITY = 1;
      public static final int NORM_PRIORITY = 5;
      public static final int MAX_PRIORITY = 10;
    
  • 从任务中返回值。Runable是执行工作的独立任务,不返回值。如需返回值需要使用Callable接口实现其call()方法,并且必须使用ExecutorService.submit()方法调用它。
import java.util.ArrayList;
import java.util.concurrent.*;
/**
 * @author : DKD
 * @Project Name : demo
 * @Package_Name : com.dkd.thread.concurrency
 * @Description : 从线程中获取返回值,ExecutorService 的submit()方法会返回一个Future对象
 * @Creation Date: 2018-10-02 16:36
 * @ModificationHistory Who    When     What
 * <p>
 * -------------   ---------------   --------------
 */
class TaskWithResult implements Callable<String> {
    private int id;
    public TaskWithResult(int id) {
        this.id = id;
    }
    @Override
    public String call() throws Exception {
        return "result of TaskWithResult " + id;
    }
}
public class CallableDemo {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();
        ArrayList<Future<String>> results = new ArrayList<>();
        for (int i = 0;i < 5; i++) {
            results.add(executorService.submit(new TaskWithResult(i)));
        }
        for (Future<String> fs : results) {
            try {
                System.out.println(fs.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                executorService.shutdown();
            }
        }
    }
}

线程池

alt text