web——7.阻塞队列

目录

1.前置知识

1.锁+volatile(线程安全保护)

2.线程通知(wait-notify)

3.各种各样的锁

读锁(共享锁)vs 写锁(独占锁)

重入锁 ReentrantLock VS  不可重入锁

公平锁fair VS 非公平锁

乐观锁 VS 悲观锁

4.锁的实现导致锁的种类

2.阻塞队列 blocking queue(FIFO)

1.blockingQueue具体方法

2.定时器

3.线程池Thread pool

解雇摸鱼状态下的正式员工?allowCoreThreadTimeout(...)

按需创建:


1.前置知识

1.锁+volatile(线程安全保护)

保护变量的内存可见性

保证代码重排序

针对long a = ...     double a = ....   的时候,可以保护它的原子性

设计模式:对一些解决通用问题的、经常书写的代码片段的总结与归纳

单例模式:通过代码,保护一个类,使得类在整个进程(应用)运行过程中有且只有一个对象

饿汉模式:一开始就初始化

懒汉模式:等用到的时候才开始初始化

2.线程通知(wait-notify)

线程和线程之间需要相互等待、通知

1.wait()和notify()方法是属于Object类的,Java中的对象都带有这两个方法

2.要使用wait和notify,必须首先对“对象”进行sunchronized加锁

含义:等待-通知

Object.wait();

Object.notify();  随机唤醒

1.加锁 2.wait的时候会释放锁(只会释放wait这个锁)3.wait的终止条件(被唤醒、被终止、假唤醒) 4.notify唤醒是随机的,notifyAll是全部唤醒   5.先notify后wait没用

3.各种各样的锁

读锁(共享锁)vs 写锁(独占锁)

目前使用的锁都是独占锁(只有一个线程能持有锁)

重入锁 ReentrantLock VS  不可重入锁

最大区别在于:是否可以允许持有锁的线程成功请求到同一把锁

synchronized锁是可重入锁

公平锁fair VS 非公平锁

非公平锁实现简单(默认)

公平:严格按照请求锁的次序获取到锁

synchronized锁是不公平的

juc下的ReentrantLock可以通过传入fair = true/false来控制是否是公平的

乐观锁 VS 悲观锁

翻译的问题:严格来讲,这两个是实现并发控制的两种不同方案,和“锁”的概念都不是一个层级的

乐观锁:评估后,并发情况,多个线程同时修改一个共享资源的情况比价少见,可以采用轻量级(无锁lock -free)方式,进行并发控制。

悲观锁:多个线程会频繁的修改同一个共享资源,必须使用互斥的方式(锁lock)来进行并发控制

4.锁的实现导致锁的种类

默认情况下,我们锁的实现,是采用OS提供的锁(mutex锁:互斥锁)

一旦请求锁失败,会导致当前线程(请求锁失败的线程)会放弃CPU,进入阻塞状态,把自己加到锁的阻塞队列中,等待被唤醒。

实现角度:互斥锁mutex VS 自旋锁spin lock

synchronized锁的实现和优化:

策略:可重入的+不公平的+独占锁

实现:

1.锁消除优化

Vector v = new Vector(); v...

前提:Vector为了做到线程安全,每个方法都使用synchronized修饰了

实际上,代码中只有主线程 -> 所有线程保护的操作都是无用功(加锁、释放锁)

编译器+JVM判断出只有一个线程时,就会消除所有锁的操作,来提升性能

2.锁的粗化优化

前提:已经没办法进行锁消除的情况

2.阻塞队列 blocking queue(FIFO)

1.blockingQueue具体方法

put(e) 结束 队列中有位置了,放入元素

            当有人让线程结束时,放入失败,也会结束,以InterruptedException形式体现

take() throw InterruptedException

poll(time,unit) throw InterruptedException

offer(e,time,unit) throw InterruptedException

生成-消费者模型:

 一个(多个线程)只负责向队列放入元素

一个(多个线程)负责从队列中取出元素

2.定时器

1.Timer类——任务调度(闹钟)

继承TimerTask类,重写run方法,指定要执行的任务

定时器执行任务时,不会占用我们的当前执行流

2.Timer实现方式:

一个延时任务需要创建一个线程

java中的Timer实现方式:一个任务,执行多个任务

3.sleep()和wait(timeout)的区别

  a.语义不同:休眠/等待   

  b.sleep一定休眠固定时间的 wait(timeout)有两个结束条件:超时时间已到、条件满足

  c.Thread静态方法 /Object的普通方法

  d.sleep和锁没有关系  wait会释放当前对象的锁

3.线程池Thread pool

矛盾:创建/销毁线程都是有成本的

有新的任务 ->创建新线程(无意义成本)->执行任务->销毁线程(无意义成本)

解雇摸鱼状态下的正式员工?allowCoreThreadTimeout(...)

corePoolSize:全部的线程上限

maximumPoolSize:全部的线程上限

keepAliveTime+unit:默认情况下>corePoolSize的线程的存活时间(没有任务时)

queue:任务队列

rejectHandle:拒绝(默认)、调用者允许、丢弃最老的、丢弃当前

按需创建:

1.一开始一个线程都没有,随着任务提交,创建core线程(当前线程数<corePoolSize)

2.优先提交队列,直到队列满

3.创建>corePoolSize的线程,直到maximumPoolSize

4.执行拒绝策略

3.多线程:并发编程总结

1.语法+OJ(数据结构+编程能力)       5

2.数据库的使用                                 4

3.多线程                                            3

         (1)理论                  2

                  a.  实际中+面试都重要的   

 1.计组+OS的基本知识

2.啥是多线程 ,什么是调度

3.多线程的不确定性

4.线程的状态

5.数据的共享、JVM运行时内存区域划分+那些区域是共享的

6.什么是线程安全

7.两个角度理解线程安全:

    1.共享&&写的操作

    2.原子性、内存可见性、代码重排序

8.JMM:java内存模型(工作内存+主内存)

9.happen-before

10.锁的理论(synchronized的使用和互斥)

11.volatile的理解

12.wait-notify

                 b. 只是面试中可能押题用的(锦上添花)

                1.锁的策略

                 2.synchronized的优化

                 3.ConcurrentHashMap(HashMao)基本知识

          (2)代码的编写        1

            原则:线程的视角,不要以类、方法为视角。 

                       类、对象、方法,完全可以被多个线程调用

                  单例模式

                  阻塞队列、定时器、线程池

                   juc下的其他类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值