当前位置: 首页 > news >正文

网站建设Skype打不开兰州seo快速优化报价

网站建设Skype打不开,兰州seo快速优化报价,荆门哪里有专门做企业网站的,长沙网站外包公司目的; JUC(java.util.concurrent) 的常⻅类 接着上一节课到 1.信号量 Semaphore 信号量, ⽤来表⽰ "可⽤资源的个数". 本质上就是⼀个计数器。 理解信号量 可以把信号量想象成是停⻋场的展⽰牌: 当前有⻋位 100 个. 表⽰有 100 个可⽤资源. 当有⻋开进去的时候,…

目的;

JUC(java.util.concurrent) 的常⻅类

接着上一节课到

1.信号量 Semaphore

信号量, ⽤来表⽰ "可⽤资源的个数". 本质上就是⼀个计数器。
理解信号量
可以把信号量想象成是停⻋场的展⽰牌: 当前有⻋位 100 个. 表⽰有 100 个可⽤资源.
当有⻋开进去的时候, 就相当于申请⼀个可⽤资源, 可⽤⻋位就 -1 (这个称为信号量的 P 操作)
当有⻋开出来的时候, 就相当于释放⼀个可⽤资源, 可⽤⻋位就 +1 (这个称为信号量的 V 操作)如果计数器的值已经为 0 了, 还尝试申请资源, 就会阻塞等待, 直到有其他线程释放资源.

 Semaphore 的 PV 操作中的加减计数器操作都是原⼦的, 可以在多线程环境下直接使⽤.

代码⽰例:
创建 Semaphore ⽰例, 初始化为 4, 表⽰有 4 个可⽤资源.
acquire ⽅法表⽰申请资源(P操作), release ⽅法表⽰释放资源(V操作)
创建 20 个线程, 每个线程都尝试申请资源, sleep 1秒之后, 释放资源. 观察程序的执⾏效果.
    public static void main(String[] args) {Semaphore semaphore = new Semaphore(3);Runnable runnable = new Runnable() {@Overridepublic void run() {try {System.out.println("申请资源");semaphore.acquire();System.out.println("我获取到资源了");Thread.sleep(1000);System.out.println("我释放资源了");semaphore.release();} catch (InterruptedException e) {e.printStackTrace();}}};for (int i = 0; i < 10; i++) {Thread t = new Thread(runnable);t.start();}}

输出结果:

2. CountDownLatch

同时等待 N 个任务执⾏结束.

案例:

构造 CountDownLatch 实例, 初始化 10 表⽰有 10 个任务需要完成.
每个任务执⾏完毕, 都调⽤ latch.countDown() . 在 CountDownLatch 内部的计数器同时⾃减.
主线程中使⽤ latch.await(); 阻塞等待所有任务执⾏完毕. 相当于计数器为 0 了.

代码:

public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(10);Runnable r = new Runnable() {@Overridepublic void run() {try {Thread.sleep(10000);latch.countDown();} catch (Exception e) {e.printStackTrace();}}};for (int i = 0; i < 10; i++) {new Thread(r).start();}// 必须等到 10 ⼈全部回来latch.await();System.out.println("⽐赛结束");}

 解释:

  1. /**第一步:设置线程A的运行次数为2/

  2. CountDownLatch latch = new CountDownLatch(10);

  1. /**第二步:递减锁存器的计数,如果计数到达零,则释放所有等待的线程**/

  2. latch.countDown();

  1. /**第三步:使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断

  2. * 如果当前的计数为零,则此方法立即返回 **/

  3. latch.await();

 CountDownLatch主要两个方法就是一是CountDownLatch.await()阻塞当前线程,二是CountDownLatch.countDown()当前线程把计数器减一。

相关⾯试题 

1. 线程同步的⽅式有哪些?
synchronized, ReentrantLock, Semaphore 等都可以⽤于线程同步.
2. 为什么有了 synchronized 还需要 juc 下的 lock?
以 juc 的 ReentrantLock 为例,
  1. synchronized 使⽤时不需要⼿动释放锁. ReentrantLock 使⽤时需要⼿动释放. 使⽤起来更灵活,
  2. synchronized 在申请锁失败时, 会死等. ReentrantLock 可以通过 trylock 的⽅式等待⼀段时间就放弃.
  3. synchronized 是⾮公平锁, ReentrantLock 默认是⾮公平锁. 可以通过构造⽅法传⼊⼀个 true 开启 公平锁模式.
  4. synchronized 是通过 Object 的 wait / notify 实现等待-唤醒. 每次唤醒的是⼀个随机等待的线程.ReentrantLock 搭配 Condition 类实现等待-唤醒, 可以更精确控制唤醒某个指定的线程.

 3. AtomicInteger 的实现原理是什么?

基于 CAS 机制,原子性

4. 信号量听说过么?之前都⽤在过哪些场景下?

信号量, ⽤来表⽰ "可⽤资源的个数". 本质上就是⼀个计数器.
使⽤信号量可以实现 "共享锁", ⽐如某个资源允许 3 个线程同时使⽤, 那么就可以使⽤ P 操作作为加锁, V 操作作为解锁, 前三个线程的 P 操作都能顺利返回, 后续线程再进⾏ P 操作就会阻塞等待, 直到前⾯的线程执⾏了 V 操作.
5. 解释⼀下 ThreadPoolExecutor 构造⽅法的参数的含义

3.线程安全的集合类

原来的集合类, ⼤部分都不是线程安全的.
Vector, Stack, HashTable, 是线程安全的(不建议⽤), 其他的集合类不是线程安全的.

3.1多线程环境使⽤ ArrayList

3.1.1.Collections.synchronizedList(new ArrayList);

synchronizedList 是标准库提供的⼀个基于 synchronized 进⾏线程同步的 List. synchronizedList
的关键操作上都带有 synchronized,可以使ArrayLis的大多数方法加锁,t变成线程安全的。

3.1.2.使⽤ CopyOnWriteArrayList 

CopyOnWrite容器即写时复制的容器
当我们往⼀个容器添加元素的时候,不直接往当前容器添加,⽽是先将当前容器进⾏Copy,复制
出⼀个新的容器,然后新的容器⾥添加元素,添加完元素之后,再将原容器的引⽤指向新的容器
这样做的好处是我们可以对CopyOnWrite容器进⾏并发的读,⽽不需要加锁,因为当前容器不会添
加任何元素。 所以CopyOnWrite容器也是⼀种读写分离的思想,读和写不同的容器。
优点:
在读多写少的场景下, 性能很⾼, 不需要加锁竞争.
缺点:
1. 占⽤内存较多.
2. 新写的数据不能被第⼀时间读取到

3.2多线程环境使⽤队列 

1. ArrayBlockingQueue
基于数组实现的阻塞队列
2. LinkedBlockingQueue
基于链表实现的阻塞队列
3. PriorityBlockingQueue
基于堆实现的带优先级的阻塞队列
4. TransferQueue
最多只包含⼀个元素的阻塞队列

3.3多线程环境使⽤哈希表(重点)

HashMap 本⾝不是线程安全的.
在多线程环境下使⽤哈希表可以使⽤:
Hashtable
ConcurrentHashMap

1) Hashtable

只是简单的把关键⽅法加上了 synchronized 关键字。

这相当于直接针对 Hashtable 对象本⾝加锁.
  1. 如果多线程访问同⼀个 Hashtable 就会直接造成锁冲突.
  2. size 属性也是通过 synchronized 来控制同步, 也是⽐较慢的.
  3. ⼀旦触发扩容, 就由该线程完成整个扩容过程. 这个过程会涉及到⼤量的元素拷⻉, 效率会⾮常低.

 

 2) ConcurrentHashMap

相⽐于 Hashtable 做出了⼀系列的改进和优化. 以 Java1.8 为例

1)读操作没有加锁(但是使⽤了 volatile 保证从内存读取结果), 只对写操作进⾏加锁. 加锁的⽅式仍然是是⽤ synchronized, 但是不是锁整个对象, ⽽是 "锁桶" (⽤每个链表的头结点作为锁对象), ⼤⼤降低了锁冲突的概率.
2)充分利⽤ CAS 特性. ⽐如 size 属性通过 CAS 来更新. 避免出现重量级锁的情况.
3)  优化了扩容⽅式: 化整为零
发现需要扩容的线程, 只需要创建⼀个新的数组, 同时只搬⼏个元素过去.
扩容期间, 新⽼数组同时存在.
后续每个来操作 ConcurrentHashMap 的线程, 都会参与搬家的过程. 每个操作负责搬运⼀⼩部分元素.
搬完最后⼀个元素再把⽼数组删掉.
这个期间, 插⼊只往新数组加.
这个期间, 查找需要同时查新数组和⽼数组

好了今天就到这里了。

http://www.tj-hxxt.cn/news/22869.html

相关文章:

  • 深圳网站维护有限公司苏州seo关键词优化推广
  • 找网站设计公司贵阳网站建设
  • 对软件工程专业的认识网站服务器速度对seo有什么影响
  • 网站设计目的与规划怎么写东莞seo优化公司
  • 网站建设哪家比较好免费域名解析网站
  • 怎么做阿里妈妈企业网站关键词网站查询
  • 北京建站模板制作深圳全网营销推广平台
  • 游戏币网站怎么做百度小说排行榜前十名
  • b2b购物网站建设seo站长论坛
  • 网站导航 javascript新浪nba最新消息
  • java网站开发文档规范应用商店aso
  • 高并发电商网站开发我要看今日头条
  • 好域名做网站河源今日头条新闻最新
  • 海口网站如何制作互联网推广渠道
  • 惠州禅城网站建设域名服务器ip查询网站
  • 做dj选歌是哪个网站网站建设山东聚搜网络
  • 百度开放云做网站举例一个成功的网络营销案例
  • 汕头有建网站公司吗googleseo推广
  • 网站抽奖模板手机推广平台有哪些
  • 长沙网上商城北京seo优化厂家
  • hbuilder开发安卓appseo推广绩效考核指标是什么
  • 做渐变色的网站百度竞价排名软件
  • 质监站网址百度服务中心投诉
  • 网站做rss wordpress百度指数行业排行
  • 刚做的网站适合做外链吗广告公司营销策划方案
  • 宁德公司做网站潍坊seo建站
  • 深圳的网站建设公司seo运营人士揭秘
  • 可以做围棋题的网站网址收录
  • 哪些网站可以做百科来源seo白帽优化
  • 营销网站建设解决方案seo网站诊断报告