代码: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相关推荐

  1. java并发编程实战wwj----------------------第一阶段--------------35-36-37-38-39

    线程一般是并发包里面的东西,我们重新写一个线程是没有必要的,我们手写线程是是为了掌握他的原理等. 线程是非常重的: 线程池为什么要有它: 线程创建要开辟虚拟机栈,释放线程要垃圾回收的. server端 ...

  2. java并发编程实战wwj----------第二阶段-------------classloader----------------42-55

    代码: 内存溢出:就是放不下了. 内存泄漏:虚拟机已经回收了但是堆内存还是一直在涨. 可以自定义classloader,可以打破双亲委派机制比如jvm. 看下上下文类加载器. 看下源码. ------ ...

  3. java并发编程实战wwj----------------------第一阶段--------------21-22-23-24-25-26

    代码:chapter7 注意一个原则,锁是加在具体的实现的方法里面的,目的是锁方法里面的共享变量的. ---------------------------------21-------------- ...

  4. java并发编程实战wwj----------------------第二阶段--------------04-05--06--07-8-9-10-11

    代码: wait线程放弃了cpu的执行权进入wait状态. Optional.of:https://www.cnblogs.com/baidawei/p/9443402.html 看下这个英文的解释. ...

  5. java并发编程实战wwj----------第三阶段-------------CompletableFuture---------------56-59

    代码: 我找的博客:https://www.cnblogs.com/happyliu/archive/2018/08/12/9462703.html 第二段代码: 这里设置的是守护线程. 代码: pa ...

  6. java并发编程实战wwj----------------------第一阶段--------------31-32-33-34

    代码: 线程的阻塞是不能打断的就是被synchronized阻塞的线程. 线程的run方法是不能抛出异常的:https://www.cnblogs.com/wxqsly/p/4275067.html ...

  7. java并发编程实战wwj----------------------第二阶段-------Future框架-------21-22-23

    有一个问题,调用者由于被调用者的阻塞而陷入阻塞. --- 代码: --- 结构思路: FutureTask:泛型接口只有一个call方法,这个是真正的做事情的. Future:泛型接口,里面只有一个g ...

  8. java并发编程实战wwj----------------------第二阶段-------不可变对象-------19-20

    不可变对象一定是线程安全的. 可变对象不一定是安全的,因为里面会加锁. ------------------------------------------------ servlet不是线程安全的, ...

  9. java并发编程实战wwj----------第三阶段-------------ConcurrentHashMap----------------73

    红黑树的总结:https://www.jianshu.com/p/5dbaa6707017 链表+数组+红黑树. 首先看下node的数据结构: static class Node<K,V> ...

最新文章

  1. 小计算器代码(C#)
  2. Netty源码分析第7章(编码器和写数据)----第2节: MessageToByteEncoder
  3. 【解题报告】Leecode 438. 找到字符串中所有字母异位词——Leecode每日一题系列
  4. 第六章:Java_异常处理
  5. 如何在python中安装matplotlib模块_Windows下为Python安装Matplotlib模块
  6. Ext.Net全部Icon图标名称展示
  7. 一文看懂PHP如何实现依赖注入
  8. 构建高性能WEB站点笔记三
  9. libsvm 的使用
  10. 怎样选择mysql的版本升级_mysql版本升级
  11. python xml转字典_python xml转成dict
  12. ULN2003的使用
  13. 字节跳动教育部分开始裁员,N+2赔付...一大波读者失业
  14. 《剑指offer》面试题46、47、49
  15. ubuntu mysql 升级_Ubuntu 升级mysql 之后的一些问题
  16. IEC 60335标准介绍
  17. 最新bilibili怎么下载视频
  18. 开发一个套crm系统软件需要多少钱
  19. MySQL 中文字段排序问题(根据中文拼音排序)
  20. 如何实现罗克韦尔PLC AB1756的远程监控数据采集?

热门文章

  1. 物联网工程设计与实施知识点
  2. 最大流之Dinic 算法
  3. 九龙擒庄指标源码破译_多年实战经验表示该指标信号一出,任何股票即刻爆涨!(附公式)...
  4. Internet互联网络提供的主要服务
  5. 【Pytorch深度学习50篇】·······第五篇:【YOLO】【1】----- YOLO V3 V4 V5的模型结构
  6. TextpatternCMS后台未过滤直接上传php导致getshell
  7. 成功集成个推后,点击推送直接跳入app指定页面
  8. 基于 Android 系统手机通讯录管理软件【100010322】
  9. pytest官方的帮助文档(英文原版)
  10. 终端电阻对CAN总线的影响