-
幼儿园的区域活动总结.doc
2021-01-18 20:02:38幼儿园区域活动总结 一、幼儿园区域活动的概念 区域活动,也称区角活动、活动区活动等,它是教师根据教育目标以及幼儿发展水平和兴趣,有目的地将活动室相对划分为不同的区域,如美工区、积木区、表演区、科学区... -
关于linux的进程与线程的概念
2013-09-01 22:23:52其特点:进程的概念主要有两点:第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的...进程:进程是操作系统结构的基础;是一个正在执行的程序!
其特点:进程的概念主要有两点:第一,进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域(text region)、数据区域(data region)和堆栈(stack region)。文本区域存储处理器执行的代码;数据区域存储变量和进程执行期间使用的动态分配的内存;堆栈区域存储着活动过程调用的指令和本地变量。第二,进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体,我们称其为进程。
但是我们不是之前学过的是,在一个时刻只能运行一个程序么?比如我的一个C语言程序执行时,是独占所有资源的!为什么??难道进程是分时的?
进程特征:
动态性:进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
[color=red]并发性:任何进程都可以同其他进程一起并发执行[/color]
独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进
结构特征:进程由程序、数据和进程控制块三部分组成
进行进程切换就是从正在运行的进程中收回处理器,然后再使待运行进程来占用处理器。
进程的三种状态
[color=red]1)就绪状态(Ready):
进程已获得除处理器外的所需资源,等待分配处理器资源;只要分配了处理器进程就可执行。就绪进程可以按多个优先级来划分队列。例如,当一个进程由于时间片用完而进入就绪状态时,排入低优先级队列;当进程由I/O操作完成而进入就绪状态时,排入高优先级队列。
2)运行状态(Running):
进程占用处理器资源;处于此状态的进程的数目小于等于处理器的数目。在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程。
3)阻塞状态(Blocked):
由于进程等待某种条件(如I/O操作或进程同步),在条件满足之前无法继续执行。该事件发生前即使把处理机分配给该进程,也无法运行。[/color] -
多线程特点
2020-08-30 17:18:341 进程 1.1 概念 就是正在运行的程序。也就是代表了程序锁占用的内存区域。...在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的。 并发性:多个进程1 进程
1.1 概念
就是正在运行的程序。也就是代表了程序锁占用的内存区域。
1.2 特点
独立性:进程是系统中独立存在的实体,它可以拥有自己的独立的资源,每一个进程都拥有自己私有的地址空间。在没有经过进程本身允许的情况下,一个用户进程不可以直接访问其他进程的地址空间。
动态性:进程与程序的区别在于,程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合。在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的。
并发性:多个进程可以在单个处理器上并发执行,多个进程之间不会互相影响
2 线程
2.1 概念
线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程可以开启多个线程。
多线程扩展了多进程的概念,使得同一个进程可以同时并发处理多个任务。
简而言之,一个程序运行后至少一个进程,一个进程里包含多个线程。
如果一个进程只有一个线程,这种程序被称为单线程。
如果一个进程中有多条执行路径被称为多线程程序
2.2 进程和线程的关系
从上图中可以看出一个操作系统中可以有多个进程,一个进程中可以有多个线程,每个进程有自己独立的内存,每个线程共享一个进程中的内存,每个线程又有自己独立的内存。(记清这个关系,非常重要!)所以想使用线程技术,得先有进程,进程的创建是OS创建的3 多线程的特性
3.1 随机性
3.2 线程状态
线程生命周期,总共有五种状态:
- 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
- 就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
- 运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
- 阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态;
- 根据阻塞产生的原因不同,阻塞状态又可以分为三种:
a) 等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
b) 同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
c) 其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。 - 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期
4 多线程创建1:继承Thread
4.1 概述
Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。Start()方法是一个native方法,它将通知底层操作系统,最终由操作系统启动一个新线程,操作系统将执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。
模拟开启多个线程,每个线程调用run()方法
4.2 常用方法
String getName()返回该线程的名称。
static Thread currentThread() 返回对当前正在执行的线程对象的引用。
void setName(String name) 改变线程名称,使之与参数 name 相同。
static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
void start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
Thread(String name) 分配新的 Thread 对象。
5 多线程创建2:实现Runnable接口
5.1 概述
如果自己的类已经extends另一个类,就无法多继承,此时,可以实现一个Runnable接口
5.2 常用方法
void run()
使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的 run 方法。5.3 比较
Thread:
优点:编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。
缺点:线程类已经继承了Thread类,所以不能再继承其他父类
Runnable
优点:线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
缺点:编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。
Callable:
优点:Runnable规定(重写)的方法是run()
Callable规定(重写)的方法是call()
Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
Call方法可以抛出异常,run方法不可以。
运行Callable任务可以拿到一个Future对象,表示异步计算的结果。
缺点:存取其他项慢6 同步锁
把有可能出现问题的代码包起来,一次只让一个线程执行。通过sychronized关键字实现同步。
当多个对象操作共享数据时,可以使用同步锁解决线程安全问题。
格式:synchronized(对象){ 需要同步的代码; }
6.1 特点
1、 前提1,同步需要两个或者两个以上的线程。
2、 前提2,多个线程间必须使用同一个锁。
3、 同步的缺点是会降低程序的执行效率, 为了保证线程安全,必须牺牲性能。
4、 可以修饰方法称为同步方法,使用的锁对象是this。
5、 可以修饰代码块称为同步代码块,锁对象可以任意
-
Java多线程:概念
2020-06-09 15:22:28文章目录Java多线程1.进程进程的概念:进程的...每一个进程都有它自己的地址空间,一般情况下,包括文本区域、数据区域和堆栈。 进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,Java多线程
1.进程
进程: 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。
进程的概念:
- 进程是一个实体。每一个进程都有它自己的地址空间,一般情况下,包括文本区域、数据区域和堆栈。
- 进程是一个“执行中的程序”。程序是一个没有生命的实体,只有处理器赋予程序生命时,它才能成为一个活动的实体。我们称其为“进程”。
进程的特征:
- 动态性:进程是动态产生、动态消亡。进程的实质是程序在多道程序系统中的一次执行过程
- 并发性:任何进程都可以同其他进程一起并发执行
- 独立性:进程是一个独立运行的基本单位,同时也是系统分配资源和调度的独立单位
- 异步性:由于进程间相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进
- 结构特征:进程由程序、数据和进程控制块三部分组成。
进程的状态分为:就绪、运行、阻塞三种。
2.线程
线程:是操作系统能到进行运算调度的最小单位。它被包含在进程中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程执行不同的任务。
-
线程是独立调度和分派的基本单位。线程可以作为操作系统内核调度的内核线程
-
同一进程中的多条线程竞共享该进程中全部系统资源。
-
一个进程可以有很多线程,每条线程并行执行不同的任务。
线程适用范围
- 服务器中的文件管理或通信控制
- 前后台处理
- 异步处理
线程特点
- 轻型实体:线程的实体包括程序、数据和TCB。线程是动态概念,它的动态特性由线程控制块TCB(Thread Control Block)描述
- 独立调度和分派的基本单位
- 可并发性
- 共享进程资源
3.线程与进程区别
- 地址空间和其他资源:进程间相互独立,同一进程的各线程间共享。
- 通信:进程间通信IPC,线程可以直接读写进程数据段来通信—需要进程同步和互斥的辅助,以保证数据的一致性。
- 调度和切换:线程上下文比进程上下文切换要快的多。
- 在多线程OS中,进程不是一个可执行的实体。
4.线程的同步
对于同步,在具体的java代码中需要完成以下两个操作:
- 把竞争访问的资源标识为private
- 同步修改哪些变量的代码,使用synchronized关键字同步方法或代码。
sychronized关键字使用说明synchronized只能标记非抽象方法,不能标识成员变量
原理
线程是进程中实体,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程不拥有系统资源,只有运行必须的一些数据结构;它与符进程的其它线程共享所拥有的全部资源。线程可以创建、撤销,从而实现程序的并发执行。一般,线程具有就绪、阻塞和运行三种基本状态
线程属性
为了正确有效使用线程,必须理解线程的各个方面。必须知道如何提供线程体、线程的生命周期、实时系统如何调度线程、线程组、什么是幽灵线程。
线程体
- 继承Thread类中的run()方法
- 实现Runnable接口的类中run()方法
- run()方法内的代码实现所产生线程的行为,它是线程的主要部分
线程状态
-
新线程(New Thread):产生一个Thread对象就生成一个新线程。仅仅是一个空线程对象,还没有分配系统资源。因此只能启动或者终止它。
-
可运行态(Runnable): start() 方法产生线程所必须的资源,调度线程执行,并且调用线程的run()方法
-
阻塞/非运行态(Not Runnable):
- suspend()方法调用
- sleep方法调用
- 线程使用wait()来等待条件变量
- 线程处于I/O请求等待
-
死亡态(Dead): run() 方法返回或者别的线程调用stop()方法,线程进入死亡转态。
线程的基本操作
- 派生:线程在进程内派生出来
- 阻塞:如果一个线程在执行过程中需要等待某个事件发生,则被阻塞
- 激活:如果阻塞线程的事件发生,则该线程被激活并进入就绪队列
- 调度:选择一个就绪线程进入执行状态
- 结束:如果一个线程执行结束,它的寄存器上下文以及堆栈内容等将被释放
线程生命周期
幽灵线程
任何一个java线程都能成为幽灵线程,它是作为运行于同一进程内的对象和线程的服务提供者。
幽灵线程是应用中典型的独立线程。它为同一应用中的其他对象提供服务。幽灵线程中的run()方法一般都是无限循环,等待服务请求。
线程组
每个java线程都是某个线程组的成员。线程组提供一种机制,使得多个线程集于一个对象内,能对他们实行整体操作。
当线程产生时,可以指定线程组或由实时系统将其放入某个缺省的线程组内。线程只能属于一个线程组,并且当线程产生后不能改变它所属的线程组。
-
操作系统概念(中文版 带书签)
2012-01-06 16:54:031 系统调用fork和 5. 3. 2 取消 5. 3. 3 信号处理 5. 3. 4 线程池 5. 3. 5 线程特定数据 5. 4 Pthread线程 5. 5 Solaris 2线程 5. 6 Windows 2000线程 5. 7 Linux线程 5. 8 Java线程 5. 8. 1 ... -
关于进程、线程的基础掌握
2020-11-19 08:37:49一、进程和线程 1、线程 1.1 概念 进程就是正在运行的程序,也就是...再进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的 并发性:多个进程可以在单个处理器上并发执一、进程和线程
1、进程
1.1 概念
进程就是正在运行的程序,也就是代表了程序所占用的内存区域
1.2 特点
- 独立性:进程是系统中独立存在的实体,可以拥有自己独立的资源,每一个进程都拥有自己私有的地址空间。在没有进程本身的允许下,一个用户进程不能直接访问其他进程的地址空间。
- 动态性:进程与程序的区别在于,程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合。再进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的
- 并发性:多个进程可以在单个处理器上并发执行,多个进程之间不会相互影响
2、线程
2.1 概念
线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程中,是进程中的实际运作单位,一个进程可以开启多个线程。
多线程扩展了多进程的概念,使得同一个进程可以同时并发处理多个任务。
简而言之,一个进程运行后至少一个线程,一个进程里可以包含了多个线程
如果一个进程只有一个线程,这种进程被称为单线程
2.2 进程和线程的关系
从上图中可以看出一个操作系统中可以有多个进程,一个进程中可以有多个线程,每个进程有自己独立的内存,每个线程共享一个进程中的内存,每个线程又有自己独立的内存。(记清这个关系,非常重要!)2.3 特性
2.3.1 随机性
在同一时刻,只能有一个程序在执行,我们感觉的这些程序在同时进行,实际上是因为cpu在高校的切换着,时间是纳秒级的
2.3.2 多线程的特性
- 原子性
一个操作或者多个操作,要么全部执行并且执行过程不会被任何因素打断,要么就都不执行
- 可见性
当多个线程访问同一个变量的时候,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值
若两个线程在不同的cpu,那么线程1改变了i的值还没刷新到主存,线程2又使用了i,那么这个i值肯定还是之前的,线程1对变量的修改线程2没看到这就是可见性问题。
- 有序性
程序执行的顺序按照代码的先后顺序执行
一般来说处理器为了提高程序运行效率,可能会对输入代码进行优化,它不保证程序中各个语句的执行先后顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码顺序执行的结果是一致的。
2.3.3 线程的状态/线程的生命周期
线程生命周期,总共有五种状态- 新建状态(new):当线程对象创建后就进入了新建状态,如 Thread t=new Thread();
- 就绪状态(Runable):当调用线程对象的start()方法(t.start(); ),线程进入了就绪状态。处于就绪状态的线程,只能说明此线程做好了准备,随时等待cpu调度运行,并不是说执行了t.start()此线程就会执行;
- 运行状态(Running):当cpu开始调度处于就绪状态的线程时,此下称才是得以真正执行,即进入到了运行状态。注:就绪状态时进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先要处于就绪状态中
- 阻塞状态(Blocked):处于运行状态的线程由于某些原因,暂时放弃对cpu的使用全,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被cpu调用以进入到运行状态
- 根据阻塞产生的原因不用,阻塞状态又可以分为三种:
- 等待阻塞:运行状态中的线程执行wait()方法,使本线程将进入到阻塞状态
- 同步阻塞:线程在获取去synchronized同步锁失败(因为锁被其他线程所占用),它会进入同步阻塞状态
- 其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态,当sllep()状态超时,join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态
- 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束了生命周期
3 线程创建
3.1 继承Thread
3.1.1 概述
本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。Start()方法是一个native方法,它将通知底层操作系统,最终由操作系统启动一个新线程,操作系统将执行run()方法。这种方式实现多线程很简单,通过自己的类extend Thread,并重写run()方法,就可以启动新线程并执行自己定义的run()方法。
但是不建议使用此方法定义线程,因为采用继承Thread的方式定义线程后,你不能在继承其他的类了,导致线程的可扩展性大大的降低,因为Java是单继承
3.1.2 流程
- 定义Thread的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体
- 创建Thread子类的实例,也就是创建了线程对象
- 启动线程,即调用线程的start()方法
3.1.3 Thread类的属性和方法
- 嵌套摘要
类型 属性 说明 static class Thread.State 线程状态。 static interface Thread.UncaughtExceptionHandler 当 Thread 因未捕获的异常而突然终止时,调用处理程序的接口。 - 属性(字段摘要)Property
类型 属性 功能 static int MAX_PRIORITY 线程可以具有的最高优先级。 static int MIN_PRIORITY 线程可以具有的最低优先级。 static int NORM_PRIORITY 分配给线程的默认优先级。 - 常用方法 Method
返回值 方法名 属性 String getName() 返回该线程的名称。 static Thread currentThread() 返回对当前正在执行的线程对象的引用。多用于实现Runnable创建线程时,调用Thread类方法的时侯 void setName(String name) 改变线程名称,使之与参数 name 相同。 static void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 void start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。 Thread.State getState() 返回该线程的状态。 void interrupt() 中断线程。 void join() 等待该线程终止。 void join(long millis) 等待该线程终止的时间最长为 millis 毫秒。 static void yield() 暂停当前正在执行的线程对象,并执行其他线程 void notify()/notifyAll() 唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。 wait()和sleep都能让线程从运行状态进入到阻塞状态,但是wait()会失去锁,而sleep不会失去锁
3.1.4 实例代码
public class ThreadTest { public static void main(String[] args) { Thread1 t = new Thread1(); t.start(); } } class Thread1 extends Thread{ @Override public void run() { for (int i=0;i<10;i++){ System.out.println(getName()+i); } } }
3.2 实现Runnable接口
3.2.1 概念
如果自己的写的类已经extends另外一个类,就无法多继承,此时,可以实现一个Runnable接口,实现这个接口的时候要重写run()方法
3.2.2 Runnable接口方法
void run()
使用实现接口 Runnable 的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的 run 方法。
3.2.3 代码示例
public class ThreadTest { public static void main(String[] args) { Thread1 t = new Thread1(); Thread thread = new Thread(t); thread.start(); } } class Thread1 implements Runnable{ @Override public void run() { for(int i=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+i); } } }
3.3 通过实现Callable接口创建线程
3.3.1 概述
3.3.2 流程
- 实现Callable接口,重写call方法,方法体写入我们的代码
- 子类的实例交给FutureTask类来包装,该FutureTask对象封装了该Callback对象的call()方法的返回值
- 使用FutureTask对象对位Thread对象的额target创建并启动新线程
- 调用FutureTask对象的get()方法来获取子线程执行结束后的返回值
public class testCallable implements Callable { public static void main(String[] args) { testCallable tt = new testCallable(); FutureTask futureTask = new FutureTask<>(tt); new Thread(futureTask).start(); try { System.out.println(futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } @Override public Object call() throws Exception { int i=0; for (;i<10;i++){ System.out.println(Thread.currentThread().getName()+i); } return i; } }
3.4 通过线程池创建线程
public class testCallable { private static int POOL_NUM=10; public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(5); for (int i=0;i<POOL_NUM;i++){ RunnableThread thread = new RunnableThread(); executorService.execute(thread); } } } class RunnableThread implements Runnable{ private int THREAD_NUM=1; @Override public void run() { for (int i=0;i<THREAD_NUM;i++){ System.out.println("线程"+Thread.currentThread()+i); } } } //执行结果 线程Thread[pool-1-thread-1,5,main]0 线程Thread[pool-1-thread-2,5,main]0 线程Thread[pool-1-thread-2,5,main]0 线程Thread[pool-1-thread-2,5,main]0 线程Thread[pool-1-thread-1,5,main]0 线程Thread[pool-1-thread-1,5,main]0 线程Thread[pool-1-thread-2,5,main]0 线程Thread[pool-1-thread-3,5,main]0 线程Thread[pool-1-thread-4,5,main]0 线程Thread[pool-1-thread-5,5,main]0
3.5 线程创建方式的比较
方式 优点 缺点 Thread 编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。 线程类已经继承了Thread类,所以不能再继承其他父类 Runnable 线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。 编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。 Callable Runnable规定(重写)的方法是,run()Callable规定(重写)的方法是call()Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。Call方法可以抛出异常,run方法不可以。运行Callable任务可以拿到一个Future对象,表示异步计算的结果。 存取其他项慢 Pool 线程池可以创建固定大小,这样无需反复创建线程对象,线程是比较耗费资源的资源同时线程不会一直无界的创建下去,拖慢系统 编程繁琐,难以理解 4 多线程并发
4.1 为什么会有并发
- Java内存模型规定了所有的变量都存储在主内存中,每条线程都有自己的工作内存
- 线程的内存中保存了该线程中用到的变量的主内存副本拷贝,线程对变量的所有操作都必须在工作内存中进行,而不能直接读写主内存
- 线程访问一个变量,首先将变量从内存中拷贝到中作内存,对变量的写操作,不会马上同步到主内存
- 不同的线程之间也无法直接访问对方内存中的变量,线程变量的传递均需要自己的工作内存和主内存之间进行数据同步进行
4.1.1 并发的的条件和后果
条件:在多线程程序中,这些线程有着共享的数据,这些线程对共享数据进项操作
后果:用商品作为例子,高并发的情况下,容易出现超卖和重卖的情况4.2 Java内存模型(JMM)
Java内存模型(JMM)作用于工作内存(本地内存)和主存之间数据同步过程,它规定了如何做数据同步以及什么时候做数据同步
4.3 并发的三要素
原子性:在一个操作中,CPU不可以在中途暂停然后再调度,即不被中断操作,要么执行完成,要么执行失败。
可见性:多个线程访问同一个变量是,一个线程改变了这个变量的值,其他变量能看到修改的值。
有序性:程序执行的顺序按照代码的先后顺序执行4.4 阻塞锁和非阻塞锁
阻塞,本质上是等待,让当前线程等待。
1.阻塞锁
就是一直循环获取锁,直到别的线程是否锁,然后该线程获取到锁为止。2.非阻塞锁
只获取一次,立即返回。4.5 锁的公平和非公平
公平就是排队,是按顺序来的;不公平就是靠竞争,随机的。
1.公平锁
线程排队队列2.非公平锁 //jdk显式锁,默认使用非公平锁
竞争4.6 乐观锁和悲观锁
乐观锁:表示多线程每次对共享资源进行操作的时候都会出现并发问题,因此在当前线程获取到锁的时候会阻塞其他的线程获取锁
悲观锁:所有线程访问共享资源的时候不会出现冲突,既然没有冲突,就不用阻塞其他的线程,如果出现冲突就是使用4.6 并发的解决方案
- 当只有一个线程写,其它线程都是读的时候,可以用volatile修饰变量
- 当多个线程写,那么一般情况下并发不严重的话可以用Synchronized,Synchronized并不是一开始就是重量级锁,在并发不严重的时候,比如只有一个线程访问的时候,是偏向锁;当多个线程访问,但不是同时访问,这时候锁升级为轻量级锁;当多个线程同时访问,这时候升级为重量级锁。所以在并发不是很严重的情况下,使用Synchronized是可以的。不过Synchronized有局限性,比如不能设置锁超时,不能通过代码释放锁。
- ReentranLock 可以通过代码释放锁,可以设置锁超时。
- 高并发下,Synchronized、ReentranLock 效率低,因为同一时刻只有一个线程能进入同步代码块,如果同时有很多线程访问,那么其它线程就都在等待锁。这个时候可以使用并发包下的数据结构,例如ConcurrentHashMap,LinkBlockingQueue,以及原子性的数据结构如:AtomicInteger。
4.7 并发解决的参考链接
4.8 同步锁synchronized
4.8.1 概念
把有可能出现问题的代码包起来,一次只让一个线程执行。通过sychroized关键字实现同步。
当多个对象操作共享数据时,可以使用同步锁解决线程安全问题4.8.2 格式
sychronized(对象){ 需要同步的代码 }
4.8.2 特点
- 前提1,同步需要两个或者两个以上的线程
- 前提2,多线程键必须使用同一个锁
- 同步的缺点是会将地程序的执行效率,为了保证线程安全,必须牺牲性能
- 可以修饰方法,修饰后称为同步方法,使用锁对象是this
- 可以修饰代码块,修饰后称为同步代码块,锁对象可以是任意的
4.8.3 CAS(compare and swap)
1 概述
什么时候使用CAS(compare/比较 and swap/交换)
当使用乐观锁策略的时候,出现冲突的时候,无锁操作使用CAS(compare and swap)又叫做比较交换来鉴别是否出现冲突,出现冲突就重试当前操作,直到没有冲突为止(有点像条件判断,满足条件才会结束,对于没有冲突的情况直接过滤,有冲突的情况会提供解决方案,能提高程序的效率)2 CAS操作过程
AS比较交换的过程可以通俗的理解为CAS(V,O,N),包含三个值分别为:V-内存地址存放的实际值;O-预期的值(旧值);N-更新的值。当V和O相同时,也就是旧值和内存中实际值相同,表明该值没有被其他线程更改过,即该旧值O就是目前来说最新的值了,自然而然可以将新值复制给V。反之,V和O不相同,表明已经被其他线程改过了,则旧值O不是最新版本的值了,所以不能把新值N赋值V,返回V即可。当多线程使用CAS操作一个变量时,只有一个变量成功,并成功更新,其余会失败。失败的线程会重新尝试,当然也可以重新挂起线程
元老级的Synchronized(未优化前)最主要的问题是:在存在线程竞争的情况下会出现线程阻塞和唤醒锁带来的性能问题,因为这是一种互斥同步(阻塞同步)。而CAS并不是武断的间线程挂起,当CAS操作失败后会进行一定的尝试,而非进行耗时的挂起唤醒的操作,因此也叫做非阻塞同步。这是两者主要的区别。3 参考链接
Sychronized的详情链接点击
-
商丘发展物流业的区位优势研究
2011-11-14 16:14:49中国的物流概念和理论的研究,是从20世纪70年代末引进西方发达国家的有关物流理念才开始展开的,发展至今已经取得了长足的进步,但在国际上还未形成一定的优势,其理论和实务仍然处于初级阶段。近些年,国内学者对于... -
Java12-多线程-同步锁及单例设计模式
2020-10-12 15:05:301 进程和线程 1.1 进程 1.1.1 概念 就是正在运行的程序。也就是代表了程序锁占用的内存区域 ...在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的。 l -
javaEE基础
2020-11-27 09:25:38Java基础 1.1 进程 1.1.1 概念 就是正在运行的程序。也就是代表了程序锁占用的内存区域。 1.1.2 特点 ...在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是 -
1 Day16--多线程1
2020-11-30 00:55:541.1进程 1.1.1概念 就是正在运行的程序。也就是代表了程序锁占用的内存区域。 1.1.2特点 ...在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具... -
java基础Day16--进程+线程
2021-02-13 21:48:591.进程 1.1 概念 就是正在运行的程序。也就是代表了程序锁...在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的 并发性:多个进程可以在单个处理器上并发执行,多个 -
java基础(16-20)
2020-09-25 17:37:39一、day16–多线程 1、进程 概念:就是正在运行的程序。也就是代表了程序锁占用的内存区域...在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的。 并发性:多个进程 -
工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究
2017-02-28 21:22:19Viewport 移动设备上的Viewport就是设备的屏幕上能用来显示网页的一块区域,即浏览器上用来显示网页的那部分区域。Viewport不局限于浏览器可视区域的大小,可能比浏览器的可视区域要大,也可能比浏览器的可视区域要... -
Java基础_进程与线程
2021-01-06 21:01:01Day_16 进程与线程 一.进程 1.定义:正在运行的程序,代表了程序锁占用的内存区域。 2.特点: ...在进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态,这些概念在程序中都是不具备的。 -
超级有影响力霸气的Java面试题大全文档
2012-07-18 09:47:04面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性: 多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化... -
讲讲多线程
2020-01-19 16:25:04一、进程 概念: 进程就是在运行中的程序,也就是代表了程序占用的内存区域。 比如:360就是一个程序,而360...动态性:进程与程序的区别在于,程序只是一个静态的指令集合,而进程是正在系统中活动的指令的集合,... -
煤炭地址问题解析解答详情
2011-06-20 11:53:4914宏观煤岩成分及宏观煤岩类型的概念、类别? 答:宏观煤岩成分:是指用肉眼或放大镜能够区别和辨认的组成煤的基本单元,它们与组成岩石的矿物相当。宏观岩成分包括:镜煤、亮煤、暗煤和丝炭四种。其中镜煤和丝炭是... -
思科网络技术学院教程CCNA1
2013-05-28 06:37:53(新)挑战性问题和实践——大多数章节的最后附加有更具挑战的复习题和实践活动。这些题目类似;于CCNA认证考试的复杂程度。 (新)额外练习——附录C包括本书中与数学运算相关的——些实践问题,你可以注册后,在... -
虚拟内存
2018-06-13 11:27:04虚拟内存将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,它高效的使用了主存。 2. 虚拟内存为每个进程提供了一致的地址空间... -
地理建模方法-徐建华
2018-10-30 11:34:02第1章 地理模型的概念、特点、功能与分类 1.1 地理模型的概念 1.1.1 模型 1.1.2 地理模型 1.2 地理模型的特点 1.3 地理模型的功能 1.3.1 认识地理问题的桥梁 1.3.2 地理科学发现的工具 1.3.3 综合研究的功能... -
软件工程知识点
2012-12-02 21:34:25甘特图表是一种常用的项目进度图表,可以直观地描述项目任务的活动分解,以及活动之间的依赖关系、资源配置情况、各项活动的进展情况等。 四、软件需求分析 1.需求分析任务 (1)用户需求 用户需求是用户关于软件... -
哈佛大学职业经理MBA全套讲义
2008-10-08 19:15:54事实上,在进行管理学专业培养的时候,为了研究利润及奖惩等问题,会遇到许多与供给、需求有关的概念。 □ 需求法则 让我们来考虑一种熟悉的产品,麦克唐纳德公司的汉堡包。一个准备购买汉堡包的人,同时还... -
[Oracle.11g权威指南(第2版)].谷长勇.扫描版.pdf
2013-06-23 21:16:09本章介绍了以下内容:包的概念和使用、集合的使用及PL/SQL的新特性。 7.1 包 156 7.1.1 包头 156 7.1.2 包体 157 7.1.3 重载 161 7.1.4 包的初始化 163 7.1.5 Oracle内置包 165 7.2 集合 165 7.2.1 index-by表 166 ... -
C#微软培训教材(高清PDF)
2009-07-30 08:51:17C#--微软.NET的第一语言 本书着重介绍语言本身,比较少... Microsoft.NET 的概念 .NET 框架 C#语言在.NET 框架中的作用及其特性 1.1 Microsoft.NET 一场新的革命 1.1.1 什么是.NET 2000 年 6 月 ... -
C#微软培训资料
2014-01-22 14:10:17Microsoft.NET 的概念 .NET 框架 C#语言在.NET 框架中的作用及其特性 1.1 Microsoft.NET 一场新的革命 1.1.1 什么是.NET 2000 年 6 月 22 日 不论对 Microsoft 还是对整个 IT 业界都将成为值得... -
综合布线工程实用技术
2018-04-29 03:06:26楼层管理区子系统分布在各个水平区子系统的各区域楼层配线间里,由跳线、跳线板、配线架、线管理器等组成,通过与垂直主干子系统之间的交连和互连,实现通道及空间管理、线缆管理、标识及彩色编码管理、接地管理等... -
ExtJS源码分析与开发实例宝典(附光盘源码) PDF扫描版
2014-09-24 23:40:05本书层次清晰,层层深入地进行例子讲解,案例丰富,介绍了Ext JS的概念和应用技巧。结合实际的项目讲解Ext JS在UI和整体项目上的应用特点,值得前端设计人员和Ajax爱好者学习。 ——成都微核科技,界面工程师,... -
即学即用:EXCEL.2007文秘与行政实战应用宝典.pdf
2013-01-31 09:53:51《Excel 2007文秘与行政实战应用宝典》针对文秘与行政管理所需求的各种信息录入、数据统计、表格制作、表单设计和图表展示,汇编出最实用、最贴近实际工作的知识和技巧,全面系统地介绍了Excel的技术特点和应用方法... -
css入门笔记
2018-05-15 14:58:57当内容多,元素区域小的时候,会产生溢出的效果,默认都是纵向溢出 属性:overflow,overflow-x,overflow-y 取值: 1.visible 可见的,默认值,溢出可见 2.hidden 隐藏的,溢出的内容全部隐藏,不可见溢出 3.... -
Google Android开发入门与实战(09年度畅销榜TOP50)--详细书签版
2013-02-08 12:00:47本书注重对实际动手能力的指导,在遵循技术研发知识体系的严密性同时,在容易产生错误、不易理解的环节配以了翔实的开发情景截图,并将重要的知识点和开发技巧以“小实验”、“小提醒”、“小知识”、“注意”等的...
-
SecureCRT 连接 GNS3/Linux 的安全精密工具
-
iptables 企业级防火墙配置(四表五链)
-
需求分析与建模最佳实践
-
破折号-源码
-
保真度与量子绝热演化之间的广义关系
-
Pytorch问题---The size of tensor a (4) must match the size of tensor b (3) at non-singletonThe size of
-
洛谷P1423 小玉在游泳经典解法
-
LVS + Keepalived 实现 MySQL 负载均衡与高可用
-
地铁读书笔记-操作系统相关术语
-
数据仓库多维数据模型设计
-
STM32F373XXDataSheet.zip
-
物联网基础篇:快速玩转MQTT
-
uni-app项目 发布为安卓 app
-
从理论到试验台,WiFi DCF网络的性能评估
-
arwin:Visual C ++项目中的arwin-源码
-
FPS游戏逆向-UE4虚幻四游戏逆向
-
构建低成本高密度Wi-Fi网络实验床
-
CS3100-UNO-源码
-
Java实现基数排序算法
-
射影级双缝光子晶体光机腔设计