Java并发编程详解读书笔记(一)

一、线程介绍

  讲线程之前得先了解进程(Peocess),现在的操作系统基本都支持多任务的进行,举个场景:有许多的程序员们喜欢边coding边听点轻音乐。这时计算机就是做并行任务,也就是有多个进程在同时进行。进程是一个具有独立功能的程序在数据集合上的一次执行过程,简言之一个进程就是一个应用程序,进程是系统进行资源分配和调度的基本单位,而一个进程至少包含一个线程(Thread),线程是进程中

的一个执行单位或执行实体,只拥有少量资源,线程也成为轻量级进程,线程是处理机(Java中为JVM)调度和分配的基本单位。

  总结:

  • 进程是系统进行资源调度和分配的基本单位
  • 线程是处理机进行调度和分配的基本单位
  • 一个进程至少包含有一个线程(包含关系)
  • 操作系统中进程的创建与撤销开销大于线程

  了解了线程的概念后我们来简单实现下边coding边听音乐:

public class TryConcurrency {

    public static void  coding() throws InterruptedException {
        while(true) {
            System.out.println("I am coding..");
            Thread.sleep(1000);
        }        
    }
    
    public static void listening() throws InterruptedException {    
        while(true) {
            System.out.println("I am listening music..");
            Thread.sleep(1000);
        }
    }
    
    public static void main(String[] args) {
        
        try {
            coding();
            listening();
        } catch (InterruptedException e) {
            
            e.printStackTrace();
        }    
    }
}
View Code

  执行后结果为:

  该结果为一直coding,并没有向我们预期那样交替执行,我们知道Java se 程序的入口为main方法,当main方法启动后,JVM进程会分配一个main线程来执行,main线程执行是自上而下的,故执行到

coding()方法是就陷入了无限循环中无法返回,故listening()方法编程了unreachable 代码,即不可达代码。我们要想让listening方法也执行就需要再使用一个线程类Thread,让两个方法“并行”执行:

public static void main(String[] args) {
        new Thread() {
            @Override
            public void run() {
                try {
                    listening();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
        
        try {
            coding();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
    }
View Code

再来看看结果:

从结果中我们可以看到达到了我们的预期。

二、线程的生命周期

  线程总共有五个生命周期,分别为:new,runnable,running,blocked,terminated。翻译为中文即:创建状态,就绪/可执行状态,运行状态,阻塞状态,终止状态。

现在来以此说说这些状态,首先Thread t = new  Thread()后该线程t就是为创建状态,而后再调用start()方法后进入就绪状态等待处理机进行调度,处理机通过轮询等方式后

就可以进入执行状态,在执行状态中以下操作会使线程进入阻塞状态:

  • 主动调用sleep,wait方法后进入waitSet中进入阻塞状态
  • 进入某个阻塞的IO操作,比如因网络数据的读写而进入阻塞状态
  • 获取某个锁资源,从而加入到该锁的阻塞队列中进入阻塞状态

线程的以下情况会使其进入terminated:

  • 线程运行正常结束,结束生命周期
  • 线程运行出错意外结束
  • JVM crash 导致所有线程都结束

三、start方法介绍分析

  我们在创建Thread线程的时候需要重写run方法,并调用start方法来启动线程。那么run方法和start方法有什么关联呢?

  阅读start源码就可以知道,首先它是判断threadStatus这个属性是否为0,为0才可以继续否则抛异常,然后再调用start0这个JNI方法,也就是本地方法。

深入分析后可以得知,线程进入执行状态之后JVM执行run方法中的执行体。 阅读玩start源码可以有以下总结:

  1. 由于首先判断threadStatus属性是否为0,可知再new Thread后初值为0,而后变化。故不可进行二次start。
  2. 一个线程执行结束,也就是到了terminated状态后,不可以再调用start方法。

  

猜你喜欢

转载自www.cnblogs.com/ring2/p/11075029.html