1、基本概念

    进程是程序的一次动态执行过程,是系统进行资源分配和调度运行的基本单位。

    线程是进程的一个实体,它是比进程更小的的能够独立运行的基本单位。在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位。线程基本自己不拥有系统资源,只拥有一点在运行中必不可少的资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统内多个程序间并发执行的程度。它可与同属一个进程中的其他线程共享进程所拥有的全部资源。

2、引入线程与进程的目的

  在OS中引入进程的目的是为了使更多的程序能够并发执行,以提高资源的利用率和系统的吞吐量。

  引入线程的则是为了减少程序在并发执行时所付出的时间开销,使OS具有更好的并发性,以进一步提高资源的利用率和系统的吞吐量。

3、程序、进程与线程的关系

  程序是保存在硬盘上的可执行代码,是一种静态的概念。

   进程是一个程序在计算机上执行的过程,是一种动态的概念。

   线程是进程的一部分,进程包含多个线程在运行。

  形象的比喻:将计算机的CPU比作一座工厂,它承担了所有的计算任务。

     由于单个CPU一次只能运行一个任务,所以此工厂一次只能供给一个车间。进程好比是这个车间,任何一个时刻CPU总是运行一个进程,其他进程处于非运行状态。

      一个车间里有很多工人协同完成一个任务,线程好比车间里的工人,一个进程可以包括多个线程。

      车间的空间是工人们共享的,这象征着一个进程的内存空间是共享的,每个其包括的线程可以使用这些共享内存。

      可每间房间的大小不同,有些房间只能容纳一个人,比如厕所,里面有人的时候,其他人就不能进入。这代表一个线程使用某些共享内存的时,其他线程必须等它结束,才能使用这一块内存。

     一个人防止他人进入的简单方法就是在门口加一把锁。先到的人锁上门,后来的人看见上锁就在门口排队,等锁打开在进入,这叫做“互斥锁”(Mutual exclusion,缩写 Mutex),防止多个线程同时读取某一块内存区。

  

  具体比如: Word程序的源代码就是保存在硬盘上的可执行代码,是静态的,当启动Word程序时对于操作系统就相当于启动了一个进程,而在这个进程还有许多功能(如拼写检查)是通过一个个线程实现的。如果Word关闭了,则这些拼写检查的线程也将消失,但是如果拼写检查的线程关闭了,也并不会让Word的进程关闭。  

4、任何线程一般具有5种状态:创建、就绪、运行、阻塞、终止

  创建状态:新建一个线程对象可采用Thread类的构造方法来实现。

    就绪状态:调用start()方法启动线程,此时线程进入线程队列排队,等待CPU的服务。

    运行状态:调运线程对象的run()方法。

    阻塞状态:在可执行状态下,如果调用sleep()、suspend()、wait()等方法,线程进入阻塞状态

        只有当引起阻塞状态的原因消失时,线程才可以进入就绪状态。

   死亡状态:调用stop()方法或run()方法执行结束时。

5、Java中的多线程

  1.Java中的实现方式:

     在Java中线要实现多线程操作有两种常用的手段: 一种是继承Thread类,另外一种是实现Runable接口。

     通过继承Thread类实现多线程必然受到单继承的局限性的影响,并且实现Runable接口适合资源共享,所以一般来说,都是通过实现Runable接口来实现多继承。

    两种方式都必须明确覆写run()方法,此方法为线程的主体。

     继承Thread类要通过start()方法启动线程,而Runable接口还是要依靠Thread类的start()方法来启动线程。

  2.Thread类与Runable接口的联系与区别:

    联系:

      1.Thread的类也是Runable接口的子类,但是Thread类中并没有完全实现Runable接口中run()方法,所以两种方式都必须明确覆写run()方法。

        public class Thread extends Object implements Runnable

      2.二者的操作方式类似于代理模式:

        Thread类与Runable接口的子类都同时实现了Runable接口,之后将Runable的子类放到Thread类的构造器中,调用Thread类的start()方法启动线程。

     区别:

      1.启动线程的方式不同

      2.局限性不同

      3.实现Runable接口的对象可以方便的实现资源的共享,而继承Thread类则多个程序之间无法共享线程类的实例对象。

      (原因:当继承Thread类实现多线程时,程序每新建一个线程都需要创建一个Thread类对象,Thread类对象的执行体run()方法是独立的,因此每个因此多个线程之间不能共享实例变量。       而以实现Runable接口的对象作为Thread对象的target,Runable实现类的run()方法仅作为Thread对象的线程执行体,而实际的的线程对象依然是Thread的实例。多个线程可以共享一个target,所以一多个线程共享一个Runable对象的实例变量。)

    3.为什么启动线程时不能直接使用run()方法:

      调用start()方法来启动线程,系统会把该run()当成线程的执行体来处理;但如果直接调用线程对象的run()方法,则run()将会被当做一个普通方法被执行,而不是线程的执行体。

6、死锁的概念

7、进程同步

   在多道程序环境下,系统中各进程以不可预测的速度向前推进,进程的异步性临界资源的访问会给系统造成混乱,造成了结果的不可再现性。为防止这种现象,引入进程同步的概念。

  对于某些资源来说,其在同一时间只能被一个进程所占用。这些一次只能被一个进程所占用的资源就是所谓的临界资源(例如现实生活中的厕所就是一个典型的临界资源)。典型的临界资源比如物理上的打印机,或是存在硬盘或内存中被多个进程所共享的一些变量和数据等(如果这类资源不被看成临界资源加以保护,那么很有可能造成丢数据的问题)。

对于临界资源的访问,必须是互诉进行。也就是当临界资源被占用时,另一个申请临界资源的进程会被阻塞,直到其所申请的临界资源被释放。而进程内访问临界资源的代码被成为临界区。

  解决同步问题的两种方式:

    同步代码块

synchronized(同步对象){
  ...
//需要同步的代码;
}

   同步方法

synchronized 关键字将一个方法声明为同步方法。
//synchronized的音标['sɪŋkrənaɪzd]

对于临界区的访问过程分为四个部分:

1.进入区:查看临界区是否可访问,如果可以访问,则转到步骤二,否则进程会被阻塞

2.临界区:在临界区做操作

3.退出区:清除临界区被占用的标志

4.剩余区:进程与临界区不相关部分的代码

8、线程池

  引入原因:

  系统启动一个新的线程的成本比较高,因为它涉及与操作系统交互。在这种情况下,使用线程池可以很好的提高性能。尤其是当程序中需要创建大量的生存期很短暂的线程时,更应该考虑使用线程池。

  实现过程:

  线程池在系统启动时即创建大量空闲的线程,程序将一个Runable对象传给线程池,线程池就会启动一个线程来执行run()方法,当run()方法结束后,该线程并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个Runable对象的run()方法。

   其他优势:

   线程池还可以有效的控制系统中并发进程的数量,通过设置线程池的最大线程数参数可以控制系统中并发线程数不超过此数,避免系统中包含大量并发线程导致JVM崩溃。

  

Java基础知识总结之多线程的更多相关文章

  1. Java基础知识强化之多线程笔记01:多线程基础知识(详见Android(java)笔记61~76)

    1. 基础知识: Android(java)学习笔记61:多线程程序的引入    ~    Android(java)学习笔记76:多线程-定时器概述和使用 

  2. Java基础知识回顾之五 ----- 多线程

    前言 在上一篇文章中,回顾了Java的集合.而在本篇文章中主要介绍多线程的相关知识.主要介绍的知识点为线程的介绍.多线程的使用.以及在多线程中使用的一些方法. 线程和进程 线程 表示进程中负责程序执行 ...

  3. Java基础知识强化之多线程笔记05:Java中继承thread类 与 实现Runnable接口的区别

    1. Java中线程的创建有两种方式:  (1)通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中. (2)通过实现Runnable接口,实例化Thread类. 2. ...

  4. Java基础知识强化之多线程笔记05:Java程序运行原理 和 JVM的启动是多线程的吗

    1. Java程序运行原理:     Java 命令会启动Java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程.该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 m ...

  5. Java基础知识强化之多线程笔记06:Lock接口 (区别于Synchronized块)

    1. 简介 我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式 ...

  6. Java基础知识强化之多线程笔记03:进程与线程 和 多线程的意义

    1. 要想了解多线程,必须先了解线程,而要想了解线程,必须先了解进程,因为线程是依赖于进程而存在. 2. 什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,我们发现只有运行的程序才会出 ...

  7. Java基础知识强化之多线程笔记02:多线程之 面试题(常问)

    1. 多线程有几种实现方案,分别是哪几种 ? 两种.   继承Thread类  实现Runnable接口 扩展一种:实现Callable接口.这个得和线程池结合. 2.  同步有几种方式,分别是什么? ...

  8. Java基础知识强化之多线程笔记07:同步、异步、阻塞式、非阻塞式 的联系与区别

    1. 同步: 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.但是一旦调用返回,就必须先得到返回值了. 换句话话说,调用者主动等待这个"调用"的结果. 对于 ...

  9. Java基础知识强化之多线程笔记04:并行和并发 区别

    1. 并发 和 并行区别 (1)并发:(单核) 并发,是在同一个cpu上同时(不是真正的同时,而是看来是同时,因为cpu要在多个程序间切换)运行多个程序. 并发是指两个任务都请求运行,而处理器只能按受 ...

随机推荐

  1. 推荐一款简单易用线上引流测试工具:GoReplay

    一. 引流测试产生背景 日常大部分的测试工作都是在测试环境下,通过模拟用户的行为来对系统进行验证,包括功能以及性能.在这个过程中,你可能会遇到以下问题: 用户访问行为比较复杂,模拟很难和用户行为一致, ...

  2. Java网络编程(二)IP、URL和HTTP

    一.IP InetAddress类有一些静态工厂方法,可以连接到DNS服务器来解析主机名. 示例1:InetAddress address = InetAddress.getByName(" ...

  3. Unity 单例模式

    明天十一放假,今天不知什么原因看到一篇unity单例模式的介绍,瞬间来了戾气. (一)最简单的单利 public class WebRequestUtility : MonoBehaviour { p ...

  4. Stringbuilder常用方法

    一.创建Stringbuilder对象StringBuilder strB = new StringBuilder(); 1.append(String str)/append(Char c):字符串 ...

  5. Spring Boot项目中如何定制servlet-filters

    本文首发于个人网站:Spring Boot项目中如何定制servlet-filters 在实际的web应用程序中,经常需要在请求(request)外面增加包装用于:记录调用日志.排除有XSS威胁的字符 ...

  6. LNMP下zabbix_server安装部署二

    上一篇中搭建完成了zabbix的web端,但是虚拟机有点问题,所以转到笔记本上来写笔记本环境 server:192.168.112.9 agent:192.168.112.8 ​ 上一篇中完成了web ...

  7. $color$有色图

    不想看题解的请速撤离 为防被骂灌输题解,撤离缓冲区 这里没字 $Ploya$神题一道,所以我自己做不出来,颓了一部分题解. 由于理(颓题)解不(没)深(脸)中途又拿了$std$对拍(输出中间结果并qj ...

  8. Linux系统移植的重要文件

    移植linux内核的关键文件:             arch/arm/mach-s5p6818/cpu.c                         cpu_init_machine()   ...

  9. EFK教程 - ElasticSearch高性能高可用架构

    通过将elasticsearch的data.ingest.master角色进行分离,搭建起高性能+高可用的ES架构 作者:"发颠的小狼",欢迎转载与投稿 目录 ▪ 用途 ▪ 架构 ...

  10. html5不能播放视频的方法

    html5不能播放视频的方法H5不能播放视频的方法 格式工厂转换成 AVC 注意音频流 采样率和比特率 设置低一点 不然播放会卡住 还有点击播放必须要click 不要用touchstart没效果的