一、线程介绍

  讲线程之前得先了解进程(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();
}
}
}

  执行后结果为:

  该结果为一直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();
} }

再来看看结果:

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

二、线程的生命周期

  线程总共有五个生命周期,分别为: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方法。

  

Java并发编程详解读书笔记(一)的更多相关文章

  1. Java并发编程的艺术读书笔记(2)-并发编程模型

    title: Java并发编程的艺术读书笔记(2)-并发编程模型 date: 2017-05-05 23:37:20 tags: ['多线程','并发'] categories: 读书笔记 --- 1 ...

  2. Java并发编程的艺术读书笔记(1)-并发编程的挑战

    title: Java并发编程的艺术读书笔记(1)-并发编程的挑战 date: 2017-05-03 23:28:45 tags: ['多线程','并发'] categories: 读书笔记 --- ...

  3. 《Java并发编程实战》读书笔记一 -- 简介

    <Java并发编程实战>读书笔记一 -- 简介 并发的历史 并发的历史,也是人类利用有限的资源去提高生产效率的一个的例子. 设想现在有台计算机,这台计算机具有以下的资源: 单核CPU一个 ...

  4. 《Java并发编程实战》学习笔记 线程安全、共享对象和组合对象

    Java Concurrency in Practice,一本完美的Java并发参考手册. 查看豆瓣读书 推荐:InfoQ迷你书<Java并发编程的艺术> 第一章 介绍 线程的优势:充分利 ...

  5. 《java并发编程实战》读书笔记2--对象的共享,可见性,安全发布,线程封闭,不变性

    这章的主要内容是:如何共享和发布对象,从而使它们能够安全地由多个线程同时访问. 内存的可见性 确保当一个线程修改了对象状态后,其他线程能够看到发生的状态变化. 上面的程序中NoVisibility可能 ...

  6. 最强Java并发编程详解:知识点梳理,BAT面试题等

    本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...

  7. 《Java并发编程的艺术》笔记

    第1章 并发编程的挑战 1.1 上下文切换 CPU通过时间片分配算法来循环执行任务,任务从保存到再加载的过程就是一次上下文切换. 减少上下文切换的方法有4种:无锁并发编程.CAS算法.使用最少线程.使 ...

  8. 《java并发编程实战》读书笔记4--基础构建模块,java中的同步容器类&并发容器类&同步工具类,消费者模式

    上一章说道委托是创建线程安全类的一个最有效策略,只需让现有的线程安全的类管理所有的状态即可.那么这章便说的是怎么利用java平台类库的并发基础构建模块呢? 5.1 同步容器类 包括Vector和Has ...

  9. 《Java并发编程实战》读书笔记(一)----- 简介

    简史 早期的计算机中不包含操作系统,从头至尾都只执行一个程序,并且这个程序能访问计算机所有资源.随着计算机发展,操作系统的出现,使得计算机可以同时运行多个程序,并且每程序都在单独的进程内运行.为什么要 ...

随机推荐

  1. 0day堆(1)堆的管理策略

    基本概念 堆块:堆区内存的基本单位 包括两个部分:块首,块身 块首:标识这个堆块自身的信息:如大小,是否被占用等 块身:分配给用户使用的数据区 堆表:一般位于堆区的起始位置,用于索引堆区所有堆块的信息 ...

  2. Codeforces Round #628 (Div. 2) 题解

    人闲桂花落,夜静春山空. 月出惊山鸟,时鸣春涧中.--王维 A. EhAb AnD gCd You are given a positive integer x. Find any such 2 po ...

  3. C#多线程(16):手把手教你撸一个工作流

    目录 前言 节点 Then Parallel Schedule Delay 试用一下 顺序节点 并行任务 编写工作流 接口构建器 工作流构建器 依赖注入 实现工作流解析 前言 前面学习了很多多线程和任 ...

  4. 基于口令的密码(PBE)

    基于口令的密码(PBE) 基于口令的密码(Password Based Encryption,PBE)是一种基于口令生成密钥,并使用该密钥进行加密的方法.其中加密和解密使用的是同一个密钥. 根据用户自 ...

  5. @SessionAttributes 和 @SessionAttribute的区别

    @SessionAttributes 和 @SessionAttribute的区别 Spring MVC中有两个长得非常像的注解:@SessionAttributes 和 @SessionAttrib ...

  6. 【Linux常见命令】vimdiff命令

    在类nuix平台,我们希望对文件之间的差异之间快速定位,希望能够很容易的进行文件合并……. 可以使用Vim提供的diff模式,通常称作vimdiff,就是这样一个能满足所有这些需求,甚至能够提供更多的 ...

  7. 数据之路 - Python爬虫 - 动态页面

    一.Ajax数据爬取 1.Ajax介绍 Ajax,全称为Asynchronous JavaScript and XML,即异步的JavaScript和XML. 它不是一门编程语言,而是利用JavaSc ...

  8. Centos 6.5升级gcc : 源码安装 + rpm安装

    1. 前言 采用Centos 6.5默认的gcc版本为4.4.7,不支持c++ 11,需要升级: 首先想到用yum命令:执行yum update gcc-c++或yum update g++ 显示没有 ...

  9. python selenium(常用关键字)

    1.文本按钮操作相关: send_keys()输入文本 from selenium import webdriver import time dr = webdriver.Chrome() dr.ge ...

  10. 在for循环里面的++i与i++的区别

    ++i与i++在表面上没有什么区别 for(语句 1;语句 2;语句 3) 语句 1 在循环(代码块)开始前执行 语句 2 定义运行循环(代码块)的条件 语句 3 在循环(代码块)已被执行之后执行 ( ...