java多线程

一. 基本概念

1.并行 多个CPU实例或是多台机器同时执行一段处理逻辑,是真正的同时

2.并发 通过CUP调度算法,让用户看上去同时去执行,实际上从CPU操作层面并不是真正的同时。并发往往需要公共的资源,对公共资源的处理和线程之间的协调是并发的难点

3.进程和线程区别

(1)  线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;

(2)  一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线

(3)  进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段,数据集,堆等)及一些进程级的资源(如打开文件和信

号等),某进程内的线程在其他进程不可见;

(4). 调度和切换:线程上下文切换比进程上下文切换要快得多

4.

(1)、新建(New):线程对象被创建时,它只会短暂地处于这种状态。此时它已经分配了必须的系统资源,并执行了初始化。例如,Thread thread = new Thread()。调用start()方法之前

(2)、就绪(Runnable):称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。

(3)、运行(Running):线程获取CPU权限进行执行。注意:线程只能从就绪状态进入运行状态。

(4)、阻塞(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态

(5)、死亡(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期

二 .线程的创建

1.继承Thread类

说明 : 实质是也是实现了runnable接口;Thread.java类中的start()方法通知”线程规划器”,此线程准备就绪,等待调用run方法;如果调用了run方法,就是同步执行效果。那么这个线程不会交给”线程规划器”来处理; Start()方法执行了不代表线程就启动了,只是通知线程规划器,等待调用run()方法

2.实现Runnable接口

三 .线程安全

1.线程安全

获得的实例变量的值是经过同步处理的,不会出现脏读的现象;方法中的变量不存在非线程安全问题,因为方法内部的变量是私有的。

2.非线程安全

多个线程对同一个对象的实例变量对象进行并发访问,产生的后果是脏读,取到的数据被修改了

3.sychronized方法解决非线程安全

(1)synchronized方法是用synchronized修饰方法,这是一种粗粒度锁;这个同步方法(非static方法)无需显式指定同步监视器,同步方法的同步监视器是this,也就是调用该方法的对象

(2) 对其他synchronized方法的调用阻塞;同一时间只有一个线程可以执行synchronized同步方法中的代码;

说明 : 能实现方法同步,两个线程共享同一个实例;synchronized取得的锁是对象锁,一个业务对象就只有一个锁

说明 : 上图中无法实现方法同步;两个线程调用的是两个不同的线程两个业务对象就会创建两个锁

4.sychronized代码块解决非线程安全问题

(1)  synchronized代码块是用synchronized修饰代码块,这是一种细粒度锁。线程开始执行同步代码块之前,必须先获得对同步监视器的锁定,任何时候只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后,该线程会释放对同步监视器的锁定

(2) synchronized(this)中的this是指当前对象,即synchronized(this)所在类对应的当前对象。它的作用是获取获取当前对象的同步锁;

5.全局锁和实例锁

 实例锁: 锁在某个实例对象上。如果该类是单例,那么该锁也是具有全局锁的概念。实例锁对应的就是synchronized关键字

全局锁:该锁针对的是类,无论实例多少个对象,那么线程都共享该锁。全局锁对应的就是static synchronized(或者是锁在该类的class或者classloader对象上)


四 .volatole关键字

1.java内存模型

所有的变量都是存储在主内存中,每个线程都是独立的工作内存,里面保存该线程使用到的变量的副本。线程对共享共享变量的所有操作必须在自己的工作内存,不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量值传递需要通过主内存来完成。例如,线程1对共享变量的修改,要想被线程2及时看到,必须经历如下两个过程:

(1)把工作内存1中更新过的变量刷新到主内存中。

(2)将主内存中最新的共享变量的值更新到线程2中。

2.并发编程中的三个概念

(1).可见性:可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值

(2).原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行,这个操作是一个不可分割的整体 ;int a=1;这个操作食必客分割的,称为一个原子操作;a++,是可分割的,不是一个原子操作

(3).有序性:即程序执行的顺序按照代码的先后顺序执行

3.volatole作用

(1) 用来确保将变量的更新操作通知其他线程

(2) 一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了:可见性,有序性,非原子性

4.使用场景

(1)  synchronized关键字是防止多个线程同时执行一段代码,那么就会很影响程序执行效率,而volatile关键字在某些情况下性能要优于synchronized,但是要注意volatile关键字是无法替代synchronized关键字的,因为volatile关键字无法保证操作的原子性

(2) 使用条件:1)对变量的写操作不依赖于当前值    2)该变量没有包含在具有其他变量的不变式中

五 .常用方法

1.常用方法

(1) wait() 让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁; Object方法

(2) notify()/notifyAll() 唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程; Object方法

(3) yield(): 作用是让步,它能让当前线程由“运行状态”进入到“就绪状态”,从而让其他具有相同优先级的等待线程获取执行权;

(4) sleep():让当前线程休眠即当前线程会从“远程状态”进入到“休眠(阻塞状态在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态”,从而等待CPU的调度执行。

(5) join():加入一个线程,一个线程可以在其他线程之上调用join()方法,其效果是等待一段时间直到第二个线程结束才继续执行。如果某个线程在另一个线程t上调用t.join(),此线程将被挂起,直到目标线程t结束才恢复(即t.isAlive()返回为假)

(6) interrupt():中断本线程,无法中断阻塞状态的线程

2.线程优先级

Java中线程的优先级的范围是1~10,默认的优先级为5。10表示最高优先级,1表示最低优先级,5是普通优先级

高优先级的线程比低优先级的线程有更高的几率得到执行

3.守护线程和用户线程

用户线程:一般用户执行用户级任务

守护线程:而守护线程也就是“后台线程”,一般用来执行后台任务

六 线程池

1.线程池好处

(1)重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销。 

(2)能有效控制线程池的最大并发数,避免大量线程之间因互相抢夺系统资源而导致的阻塞现象。 

(3)能够对线程进行简单的管理,并提供定时执行以及指向间隔循环执行等功能。

2.线程池的创建

(1) Java SE 5的java.util.concurrent包中的执行器(Executor)管理Thread对象;Executor在客户端和任务执行之间提供了一个间接层;与客户端直接执行任务不同,这个中介对象将执行任务

(2) ThreadPoolExecutor线程池类

存放一定数量的一个线程集合。线程池允许若个线程同时运行,运行同时运行的线程数量就是线程池的容量。当添加到线程池中的线程超过它的容量时,会有一部分线程阻塞等待,线程池会通过相应的调度策略和拒绝策略,对添加到线程池中的线程进行管理

(3) 线程池的分类

fixedThreadPool: 通过Executor的newFixedThreadPool方法来创建;只有核心线程并且这些核心线程不会被回收,这意味着它能过更加快速的相应外界的请求;并且这些核心线程没有超时机制,另外任务队列也是没有大小限制的;可以一次性预先执行代价高昂的线程分配,因而也就可以限制线程的数量了。这可以节省时间,因为你不用为每个任务都固定的付出创建线程的开销

LinkedBlockingQueue阻塞队列

singleThreadExcutor:通过Executor的newSingleThreadExecutor方法来创建。这类线程池内部只有一个核心线程,它确保所有的任务都在同一个线程中按顺序执行;SingleThreadExecutor的意义在于统一所有的外界任务到一个线程中,这使得这些任务之间不需要处理线程同步的问题

schedulThreadPool:通过Executors的newScheduledPool方法来创建。它的核心线程数量时固定的,而非核心线程数是没有限制的,并且当非核心线程闲置是会被立即回收;ScheduledThreadPool这类线程主要用于执行定时任务和具有固定周期的重复任务

cachedThreadPool:通过Executors的newCachedThreadPool方法来创建。它是一种线程数量不定的线程池,它只有非核心线程,并且其最大线程数为Integer.MAX_VALUE;和FixedThreadPool不同的是,CachedThreadPool的任务队列其实相当于一个空集合,这将导致任何任务都会立即被执行

参考文档1:https://blog.csdn.net/wanliguodu/article/details/81005560

参考文档2:https://blog.csdn.net/wanliguodu/article/details/81071562#_803

参考文档3:https://blog.csdn.net/wanliguodu/article/details/81154294

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271