实战Java高并发程序设计/第二章 Java并行程序基础 1

 

2020.8.16开始阅读学习 葛一鸣<<实战Java高并发程序设计>>

第二章 Java并行程序基础

使用多线程而不是多进程进行并发程序的设计 ,线程间的切换和调度成本远远小于进程

 

2.1线程的基本概念

线程(Thread) 轻量级的进程,程序执行的最小单位
进程(Process) 计算机程序关于某数据集合的一个运行活动,是系统进行资源的分配和调度的基本单位.

程序的概念
程序是指令,数据及组成形式的描述,进程是程序的实体
线程和进程的关系
进程是线程的容器,进程中可以容纳若干线程
说明
在Windows中,后缀为.exe的文件就是程序 ,是静态的,程序是"死的",双击后,指令被加载,会得到一个进程,进程是"活的",程序(进程)开始执行,
在一个进程中.可以包含若干的线程,来执行具体的程序(进程).


2.2.1线程的生命周期

          

 

 在Thread 类中 定义了一个 枚举类 State 来 定义了 线程的状态(NEW 新建, RUNABLE 就绪, BLOCKED 阻塞, WAITING 等待, TIMED_WAITING有时等待,TERMINATED结束)

          

 

 public enum State {

NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}

新建状态 Thread t = new Thread();
就绪状态 t.start();
阻塞状态 线程执行中遇到 synchronized
等待状态 WAITING 无时间限制等待 TIMED_WAITING 有时间限制等待
结束状态 线程执行完毕


2.2.2 start()方法和run()方法的区别
                  

 

 

start()方法 和 run()方法 都是Thread类的方法 还有一个start0()方法

结合源码注释所述
start()方法是线程执行的原因,JVM会调用run()方法来执行这个线程
结果是两个线程在同时执行,一个执行start()方法,一个执行run()方法

过程中start()方法中会调用start0()方法 (native 修饰的方法) 通知JVM调用run()方法
start()方法 是线程可以执行的标志(开启线程了)
run()方法 是线程执行的具体内容,仅仅Thread.run(),不会开启一个线程,它只是一个普通方法,只会串行的执行run()方法中的代码

 

 

 

 

 

Thread类 实现了Runnable接口 重写了run()方法
所以创建线程的方法
一 继承Thread类 重写run()方法

public class myThread extends Thread {
   @Override
   public void run() {
      System.out.println("继承Thread类 创建线程");
   }

   public static void main(String[] args) {
      myThread myThread = new myThread();
      myThread.start();
   }
}

 

二 实现Runnable接口 重写run()方法 (Thread类本身也是这么做的,直接实现Runnable接口,避免了重写Thread.run()方法)

说明 在Thread的run方法中 target 就是 Runable实例
Thread的构造方法 也是传入一个Runnable实例 public Thread(Runnable target)

public class myRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("实现Runnable接口 创建线程");
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new myRunnable());
        thread.start();
    }
}

 

三 实现Callabel接口 重写call()方法

FutureTask task = new FutureTask(new myCallable());
new Thread(task).start();

FutureTask类实现了RunnableFuture接口,RunnableFuture接口继承了Future和Runnable接口。

说明 FutureTask类可以作为Runnable实例 构造一个Thread类


public class myCallable implements Callable {
    @Override
    public Object call() throws Exception {
        StringBuffer buffer = new StringBuffer();
        buffer.append("实现Callable接口 ");
        buffer.append("创建线程");
        return buffer.toString();
    }

    public static void main(String[] args) throws Exception {
        FutureTask<myThread> task = new FutureTask<>(new myCallable());
        new Thread(task).start();
        System.out.println(task.get());
    }
}

 

FutureTask类重写的run()方法 调用了传入的Callabel()接口的call()方法

 

 

四 使用线程池创建线程
ExecutorService executorService = Executors.newSingleThreadExecutor();

submit 方法可以接收Runnable Callable实例

public class myThreadPool {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("线程池创建线程");
            }
        });
        executorService.shutdown();
    }
}

 

posted @ 2020-08-16 19:41  wf.zhang  阅读(206)  评论(0编辑  收藏  举报