java并发编程实战wwj----------------------第一阶段--------------27-28-29-30
代码:chapter9
sleep:是Thread的方法,sleep不释放锁,sleep不用synchronized,不需要被唤醒。
wait:所有对象的方法,wait释放锁,
用synchronized,要被唤醒。
如何使用这个案例:切换m1和m2方法。
chapter9
package one.chapter9;import java.util.stream.Stream;public class DifferenceOfWaitAndSleep {private final static Object LOCK = new Object(); // 定义锁一定要定义final类型的public static void main(String[] args) {Stream.of("T1", "T2").forEach(name ->new Thread(name) {@Overridepublic void run() {m1();}}.start());}public static void m1() {synchronized (LOCK) {try { System.out.println("The Thread " + Thread.currentThread().getName() + " enter.");Thread.sleep(20000);} catch (InterruptedException e) {e.printStackTrace();}}}public static void m2() {synchronized (LOCK) {try {System.out.println("The Thread " + Thread.currentThread().getName() + " enter.");LOCK.wait();} catch (InterruptedException e) {e.printStackTrace();}}}
}
----------------------------------------27-----------sleep和wait的区别-------------------
先start之后才可以join。先设置守护线程才可以start。
线程的数量的优化图,多了上下文就多了会有开销的。
卡了看看是不是线程太多了。
jdk8的::https://blog.csdn.net/csmans/article/details/82256690
---
问题:10000台机器如何用100个线程采集,线程多了会有问题,上下文切换。
代码:
package one.chapter9;import java.util.*;public class CaptureService {final static private LinkedList<Control> CONTROLS = new LinkedList<>();private final static int MAX_WORKER = 5;public static void main(String[] args) {List<Thread> worker = new ArrayList<>();Arrays.asList("M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10").stream().map(CaptureService::createCaptureThread).forEach(t -> {t.start();worker.add(t);});// 在这里去通体的joinworker.stream().forEach(t -> {try {t.join();} catch (InterruptedException e) {e.printStackTrace();}});Optional.of("All of capture work finished").ifPresent(System.out::println);}private static Thread createCaptureThread(String name) {return new Thread(() -> {Optional.of("The worker [" + Thread.currentThread().getName() + "] BEGIN capture data.").ifPresent(System.out::println);synchronized (CONTROLS) {while (CONTROLS.size() > MAX_WORKER) {//要是有5个就乖乖等着就可以try {CONTROLS.wait();} catch (InterruptedException e) {e.printStackTrace();}}CONTROLS.addLast(new Control());//跳出while就说明可以跑了加入跑的队列 对公共数据操作要串行化保护的}// 这个是并行的Optional.of("The worker [" + Thread.currentThread().getName() + "] is working...").ifPresent(System.out::println);try {Thread.sleep(10000);} catch (InterruptedException e) {//采集时间是10S 并行去执行任务e.printStackTrace();}synchronized (CONTROLS) {//工作完了我吧自己移除工作队列Optional.of("The worker [" + Thread.currentThread().getName() + "] END capture data.").ifPresent(System.out::println);CONTROLS.removeFirst();// 为什么remove// first?删掉的可能是自己也肯能是别人只要删掉就可以了 其实CONTROLS.notifyAll();}}, name);}private static class Control {}
}
对公共数据的操作要设置同步的保护的,这是真理。
------------------------------28----------控制并发-------------------------
自定义的锁解决synchronized的慢的问题:
代码chapter10
代码:
第一步:写一个接口
定义显示锁:
public interface Lock {class TimeOutException extends Exception {public TimeOutException(String message) {//报错信息super(message);}}void lock() throws InterruptedException;//加锁void lock(long mills) throws InterruptedException, TimeOutException;//没有获取到锁就退出来了void unlock();//释放锁Collection<Thread> getBlockedThread();//获得被阻塞的线程int getBlockedSize();//获得被阻塞的线程的个数}
先看下最终的代码
package one.chapter10;import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;public class BooleanLock implements Lock {//The initValue is true indicated the lock have be get.//The initValue is false indicated the lock is free (other thread can get this.)private boolean initValue;// 被阻塞的线程private Collection<Thread> blockedThreadCollection = new ArrayList<>();private Thread currentThread;//为什么第一这个变量,谁加的锁只能由谁去释放的。public BooleanLock() {this.initValue = false;}@Overridepublic synchronized void lock() throws InterruptedException {while (initValue) {//true就是我不能抢到锁了就得等着if(!blockedThreadCollection.contains(Thread.currentThread())){blockedThreadCollection.add(Thread.currentThread());}this.wait();// 就在lock上wait}blockedThreadCollection.remove(Thread.currentThread());this.initValue = true;this.currentThread = Thread.currentThread();//设置lock是当前的线程虽然抢锁失败了}@Overridepublic synchronized void unlock() {//这个synchronized锁的是BooleanLock的实例if (Thread.currentThread() == currentThread) {//是当前的线程才释放的this.initValue = false;Optional.of(Thread.currentThread().getName() + " release the lock monitor.").ifPresent(System.out::println);this.notifyAll();}}@Overridepublic synchronized void lock(long mills) throws InterruptedException, TimeOutException {if (mills <= 0)lock();long hasRemaining = mills;//需要等的时间long endTime = System.currentTimeMillis() + mills;//到什么时间结束while (initValue) {//需要等待 醒了我就去抢锁,抢不到我就加时间 多次醒了请不到我就超时了 我直接抛出异常了if (hasRemaining <= 0)throw new TimeOutException("Time out");if(!blockedThreadCollection.contains(Thread.currentThread())){blockedThreadCollection.add(Thread.currentThread());}this.wait(mills);hasRemaining = endTime - System.currentTimeMillis();}blockedThreadCollection.remove(Thread.currentThread());this.initValue = true;this.currentThread = Thread.currentThread();}/*** 注意这个要考线程安全 其他的线程可以在其他的方法操作这个集合* @return*/@Overridepublic Collection<Thread> getBlockedThread() {return Collections.unmodifiableCollection(blockedThreadCollection);}@Overridepublic int getBlockedSize() {return blockedThreadCollection.size();}
}
----------29--------------------------------
第一个一个bug:
t1加的锁只能t1去释放,其他的是不能去释放的。
@Overridepublic synchronized void lock() throws InterruptedException {while (initValue) {//true就是我不能抢到锁了就得等着if(!blockedThreadCollection.contains(Thread.currentThread())){blockedThreadCollection.add(Thread.currentThread());}this.wait();}blockedThreadCollection.remove(Thread.currentThread());this.initValue = true;this.currentThread = Thread.currentThread();//Thread.currentThread()这个是获取到锁的线程}@Overridepublic synchronized void unlock() {//这个synchronized锁的是BooleanLock的实例if (Thread.currentThread() == currentThread) {//是当前的线程才释放的this.initValue = false;Optional.of(Thread.currentThread().getName() + " release the lock monitor.").ifPresent(System.out::println);this.notifyAll();}}
第二个问题:synchronized不能打断,导致等待时间长,这个是synchronized的工作机制。
package chapter10;public class SynchronizedProblem {public static void main(String[] args) throws InterruptedException {new Thread() {@Overridepublic void run() {SynchronizedProblem.run();}}.start();Thread.sleep(1000);Thread t2 = new Thread() {@Overridepublic void run() {
// /sdfsdfsdSynchronizedProblem.run();//sdfsdfsdSystem.out.println("继续做以下的事情t");}};t2.start();Thread.sleep(2000);t2.interrupt();System.out.println(t2.isInterrupted());}private synchronized static void run() {System.out.println(Thread.currentThread());while (true) {}}
}
t2可以打断但是不能中断进入
t2是一直block住的。我们不能让t2释放回来。做线程的其他的事情。
我们要解决这个问题。
@Overridepublic synchronized void lock(long mills) throws InterruptedException, TimeOutException {if (mills <= 0)lock();long hasRemaining = mills;//需要等的时间long endTime = System.currentTimeMillis() + mills;//到什么时间结束while (initValue) {//需要等待 醒了我就去抢锁,抢不到我就加时间 多次醒了请不到我就超时了 我直接抛出异常了if (hasRemaining <= 0)throw new TimeOutException("Time out");if(!blockedThreadCollection.contains(Thread.currentThread())){blockedThreadCollection.add(Thread.currentThread());}this.wait(mills);hasRemaining = endTime - System.currentTimeMillis();}blockedThreadCollection.remove(Thread.currentThread());this.initValue = true;this.currentThread = Thread.currentThread();}
-------------------------------30-------------------------------
java并发编程实战wwj----------------------第一阶段--------------27-28-29-30相关推荐
- java并发编程实战wwj----------------------第一阶段--------------35-36-37-38-39
线程一般是并发包里面的东西,我们重新写一个线程是没有必要的,我们手写线程是是为了掌握他的原理等. 线程是非常重的: 线程池为什么要有它: 线程创建要开辟虚拟机栈,释放线程要垃圾回收的. server端 ...
- java并发编程实战wwj----------第二阶段-------------classloader----------------42-55
代码: 内存溢出:就是放不下了. 内存泄漏:虚拟机已经回收了但是堆内存还是一直在涨. 可以自定义classloader,可以打破双亲委派机制比如jvm. 看下上下文类加载器. 看下源码. ------ ...
- java并发编程实战wwj----------------------第一阶段--------------21-22-23-24-25-26
代码:chapter7 注意一个原则,锁是加在具体的实现的方法里面的,目的是锁方法里面的共享变量的. ---------------------------------21-------------- ...
- java并发编程实战wwj----------------------第二阶段--------------04-05--06--07-8-9-10-11
代码: wait线程放弃了cpu的执行权进入wait状态. Optional.of:https://www.cnblogs.com/baidawei/p/9443402.html 看下这个英文的解释. ...
- java并发编程实战wwj----------第三阶段-------------CompletableFuture---------------56-59
代码: 我找的博客:https://www.cnblogs.com/happyliu/archive/2018/08/12/9462703.html 第二段代码: 这里设置的是守护线程. 代码: pa ...
- java并发编程实战wwj----------------------第一阶段--------------31-32-33-34
代码: 线程的阻塞是不能打断的就是被synchronized阻塞的线程. 线程的run方法是不能抛出异常的:https://www.cnblogs.com/wxqsly/p/4275067.html ...
- java并发编程实战wwj----------------------第二阶段-------Future框架-------21-22-23
有一个问题,调用者由于被调用者的阻塞而陷入阻塞. --- 代码: --- 结构思路: FutureTask:泛型接口只有一个call方法,这个是真正的做事情的. Future:泛型接口,里面只有一个g ...
- java并发编程实战wwj----------------------第二阶段-------不可变对象-------19-20
不可变对象一定是线程安全的. 可变对象不一定是安全的,因为里面会加锁. ------------------------------------------------ servlet不是线程安全的, ...
- java并发编程实战wwj----------第三阶段-------------ConcurrentHashMap----------------73
红黑树的总结:https://www.jianshu.com/p/5dbaa6707017 链表+数组+红黑树. 首先看下node的数据结构: static class Node<K,V> ...
最新文章
- 小计算器代码(C#)
- Netty源码分析第7章(编码器和写数据)----第2节: MessageToByteEncoder
- 【解题报告】Leecode 438. 找到字符串中所有字母异位词——Leecode每日一题系列
- 第六章:Java_异常处理
- 如何在python中安装matplotlib模块_Windows下为Python安装Matplotlib模块
- Ext.Net全部Icon图标名称展示
- 一文看懂PHP如何实现依赖注入
- 构建高性能WEB站点笔记三
- libsvm 的使用
- 怎样选择mysql的版本升级_mysql版本升级
- python xml转字典_python xml转成dict
- ULN2003的使用
- 字节跳动教育部分开始裁员,N+2赔付...一大波读者失业
- 《剑指offer》面试题46、47、49
- ubuntu mysql 升级_Ubuntu 升级mysql 之后的一些问题
- IEC 60335标准介绍
- 最新bilibili怎么下载视频
- 开发一个套crm系统软件需要多少钱
- MySQL 中文字段排序问题(根据中文拼音排序)
- 如何实现罗克韦尔PLC AB1756的远程监控数据采集?
热门文章
- 物联网工程设计与实施知识点
- 最大流之Dinic 算法
- 九龙擒庄指标源码破译_多年实战经验表示该指标信号一出,任何股票即刻爆涨!(附公式)...
- Internet互联网络提供的主要服务
- 【Pytorch深度学习50篇】·······第五篇:【YOLO】【1】----- YOLO V3 V4 V5的模型结构
- TextpatternCMS后台未过滤直接上传php导致getshell
- 成功集成个推后,点击推送直接跳入app指定页面
- 基于 Android 系统手机通讯录管理软件【100010322】
- pytest官方的帮助文档(英文原版)
- 终端电阻对CAN总线的影响