发布于2021-06-12 14:42 阅读(94) 评论(0) 点赞(25) 收藏(2)
a)lock写在try之前
b)一定要记得在finally里面进行unlock()
acquire():void ------>尝试获取锁,如果可以正常获取到,则执行后面的业务逻辑,如果获取失败,则阻塞等待
release():void------>释放锁
//信号量演示
public class ThreadMain98 {
public static void main(String[] args) {
//创建信号量
Semaphore semaphore=new Semaphore(2,true);
ThreadPoolExecutor executor=new ThreadPoolExecutor(10,10,
0, TimeUnit.SECONDS,new LinkedBlockingQueue<>(100));
for (int i = 0; i <4 ; i++) {
//创建任务
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"到达停车场");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//试图进入停车场
try {
//尝试获取锁
semaphore.acquire();
//当代码只想到此处,说明已经获取到锁
System.out.println(Thread.currentThread().getName()+"进入停车场---------");
//车辆停留的时间
int num=1+new Random().nextInt(5);
try {
Thread.sleep(num*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"离开停车场...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放锁
semaphore.release();
}
}
});
}
}
}
计数器是用来保证一组线程同时完成某个操作之后,才能继续之后的任务。
await():void-----等待(当线程数量不满足CountDownLauth的数量的时候,会执行此代码会阻塞等待,直到数量满足之后,在执行await之后的代码。)
countDown():void
答:CountDownLauth里面有一个计数器,计数器的数量在初始化的时候设置,每次调用countDown()方法的时候,计数器的数量-1,直到减到0之后,就可以执行await之后的代码。
import java.util.concurrent.CountDownLatch;
/**
* 计数器
*/
public class ThreadMain99 {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch=new CountDownLatch(5);
for (int i = 1; i <6 ; i++) {
int finaI=i;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始起跑");
try {
Thread.sleep(finaI*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"到达终点");
//将计数器-1
latch.countDown();
}
}).start();
}
//阻塞等待
latch.await();
System.out.println("所有人都到达终点了,公布排名");
}
}
声明计数器初始值为5
当计数器减到0之后,在执行await
CountDownLauth计数器的使用是一次性的,当用完一次之后就不能使用了
await():int ------等待(CyclicBarrier里面有一个计数器,每次执行await方法的时候,计数器的数量-1,直到减到0之后,就可以执行await之后的代码,并且此时会将count值(计数器的值)重置继续利用。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* 循环屏障
*/
public class ThreadMain100 {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier=new CyclicBarrier(5, new Runnable() {
@Override
public void run() {
System.out.println("执行了CyclicBarrier里面的Runnable");
}
});
for (int i = 1; i < 11; i++) {
int finalI=i;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始起跑");
try {
Thread.sleep(finalI*200);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println(Thread.currentThread().getName()+"等待其他人-----------");
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
//代码执行到此行,说明已经有一组代码已经满足情况
System.out.println(Thread.currentThread().getName()+"执行结束");
}
}).start();
}
}
}
1.计数器-1
2.判断计数器是否为0,如果为0执行之后的代码,如果不为0阻塞等待
当计数器为0时,首先会执行await之后的代码,将计数器重置
答:CountDownLatch计数器只能使用一次,CyclicBarrier他的计数器可以重复使用。
HashMap底层实现结构,负载因子,哈希冲突的解决等…线程问题
HashMap------非线程安全的容器
——JDK1.7死循环(要会画出来)
——JDK1.8数据覆盖
HashMap—>数组+链表 / 红黑树
HashMap 负载因子(加载因子)0.75 扩容:16*0.75=进行扩容
0.75:尽量的避免哈希冲突所带来的性能开销问题(空间换时间的方案)
JDK1.7是将ConcurrentHashMap分成几个segment进行加锁(分段锁)。
JDK1.8锁优化:读的时候不加锁,写的时候加锁,使用了大量的CAS,Voiltail…
给put方法直接加锁,因此一般情况不会使用Hashtable
原文链接:https://blog.csdn.net/qq_54850622/article/details/117715269
作者:哦哦好吧
链接:http://www.javaheidong.com/blog/article/222384/4a47a6dfd6c1613bf2e0/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!