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

天河区建设水务局网站wordpress动漫整站

天河区建设水务局网站,wordpress动漫整站,做企业网站要不要我们自己提供网站相关的图片?,dedecms做地方网站1. 等待唤醒机制 由于线程的随机调度#xff0c;可能会出现“线程饿死”的问题#xff1a;也就是一个线程加锁执行#xff0c;然后解锁#xff0c;其他线程抢不到#xff0c;一直是这个线程在重复操作 void wait() 当前线程等待#xff0c;直到被其他线程唤醒 void no… 1. 等待唤醒机制 由于线程的随机调度可能会出现“线程饿死”的问题也就是一个线程加锁执行然后解锁其他线程抢不到一直是这个线程在重复操作 void wait() 当前线程等待直到被其他线程唤醒 void notify() 随机唤醒单个线程 void notifyAll() 唤醒所有线程 等待wait当一个线程执行到某个对象的wait()方法时它会释放当前持有的锁如果有的话并进入等待状态。此时线程不再参与CPU的调度直到其他线程调用同一对象的notify()或notifyAll()方法将其唤醒类似的wait() 方法也可以传入一个参数表示等待的时间不加参数就会一直等 唤醒notify/notifyAll: notify: 唤醒在该对象监视器上等待的某个线程如果有多个线程在等待那么具体唤醒哪一个是随机的 notifyAll: 唤醒在该对象监视器上等待的所有线程 1.1. wait 上面的方法是Object提供的方法所以任意的Object对象都可以调用下面来演示一下 public class ThreadDemo14 {public static void main(String[] args) throws InterruptedException {Object obj new Object();System.out.println(wait前);obj.wait();System.out.println(wait后);} } 结果抛出了一个异常非法的锁状态异常也就是调用wait的时候当前锁的状态是非法的 这是因为在wait方法中会先解锁然后再等待所以要使用wait就要先加个锁阻塞等待就是把自己的锁释放掉再等待不然一直拿着锁等待其他线程就没机会了 把wait操作写在synchronized方法里就可以了运行之后main线程就一直等待中在jconsole中看到的也是waiting的状态 注意wait操作进行解锁和阻塞等待是同时执行的打包原子如果不是同时执行就可能刚解锁就被其他线程抢占了然后进行了唤醒操作这时原来的线程再去等待已经错过了唤醒操作就会一直等 wait执行的操作1. 释放锁并进入阻塞等待准备接收唤醒通知 2. 收到通知后唤醒并重新尝试获得锁 1.2. notify 接下来再看一下notify方法 public class ThreadDemo15 {private static Object lock new Object();public static void main(String[] args) {Thread t1 new Thread(()-{synchronized (lock){System.out.println(t1 wait 前);try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(t1 wait 后);}});Thread t2 new Thread(()-{synchronized (lock){System.out.println(t2 notify 前);Scanner sc new Scanner(System.in);sc.next();//这里的输入主要是构造阻塞lock.notify();System.out.println(t2 notify 后);}});} } 然后就会发现又出错了还是之前的错误notify也需要先加锁才可以 把之前的notify也加进synchornized就可以了并且还需要确保是同一把锁 调用wait方法的线程会释放其持有的锁被唤醒的线程在执行之前必须重新获取被释放的锁 public class Cook extends Thread {Overridepublic void run() {while (true) {synchronized (Desk.lock) {if (Desk.count 0) {break;} else {if (Desk.foodFlag 0) {try {Desk.lock.wait();//厨师等待} catch (InterruptedException e) {e.printStackTrace();}} else {Desk.count--;System.out.println(还能再吃 Desk.count 碗);Desk.lock.notifyAll();//唤醒所有线程Desk.foodFlag 0;}}}}} } public class Foodie extends Thread {Overridepublic void run() {while (true) {synchronized (Desk.lock) {if (Desk.count 0) {break;} else {if (Desk.foodFlag 1) {try {Desk.lock.wait();} catch (InterruptedException e) {e.printStackTrace();}} else {System.out.println(已经做好了);Desk.foodFlag 1;Desk.lock.notifyAll();}}}}} } public class Desk {public static int foodFlag 0;public static int count 10;//锁对象public static Object lock new Object(); } 这里实现的功能就是厨师做好食物放在桌子上美食家开始品尝如果桌子上没有食物美食家就等待有的话厨师进行等待 sleep() 和 wait() 的区别 这两个方法看起来都是让线程等待但是是有本质区别的使用wait的目的是为了提前唤醒sleep就是固定时间的阻塞不涉及唤醒虽然之前说的Interrupt可以使sleep提前醒来但是Interrupt是终止线程并不是唤醒wait必须和锁一起使用wait会先释放锁再等待sleep和锁无关不加锁sleep可以正常使用加上锁sleep不会释放锁抱着锁一起睡其他线程无法拿到锁 在刚开始提到过如果有多个线程都在同一个对象上wait那么唤醒哪一个线程是随机的 public class ThreadDemo16 {private static Object lock new Object();public static void main(String[] args) {Thread t1 new Thread(() - {synchronized (lock) {System.out.println(t1 wait 前);try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(t1 wait 后);}});Thread t2 new Thread(() - {synchronized (lock) {System.out.println(t2 wait 前);try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(t2 wait 后);}});Thread t3 new Thread(() - {synchronized (lock) {System.out.println(t3 wait 前);try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(t wait 后);}});Thread t4 new Thread(() - {synchronized (lock) {System.out.println(t4 notify 前);Scanner sc new Scanner(System.in);sc.next();lock.notify();System.out.println(t4 notify 后);}});t1.start();t2.start();t3.start();t4.start();} } 这次只是t1被唤醒了 还可以使用notifyAll把全部的线程都唤醒 2. 阻塞队列 2.1. 阻塞队列的使用 阻塞队列是一种特殊的队列相比于普通的队列它支持两个额外的操作当队列为空时获取元素的操作会被阻塞直到队列中有元素可用当队列已满时插入元素的操作会被阻塞直到队列中有空间可以插入新元素。 当阻塞队列满的时候线程就会进入阻塞状态 public class ThreadDemo19 {public static void main(String[] args) throws InterruptedException {BlockingDequeInteger blockingDeque new LinkedBlockingDeque(3);blockingDeque.put(1);System.out.println(添加成功);blockingDeque.put(2);System.out.println(添加成功);blockingDeque.put(3);System.out.println(添加成功);blockingDeque.put(4);System.out.println(添加成功);} } 同时当阻塞队列中没有元素时再想要往外出队线程也会进入阻塞状态 public class ThreadDemo20 {public static void main(String[] args) throws InterruptedException {BlockingDequeInteger blockingDeque new LinkedBlockingDeque(20);blockingDeque.put(1);System.out.println(添加成功);blockingDeque.put(2);System.out.println(添加成功);blockingDeque.take();System.out.println(take成功);blockingDeque.take();System.out.println(take成功);blockingDeque.take();System.out.println(take成功);} } 2.2. 实现阻塞队列 根据阻塞队列的特性可以尝试来自己手动实现一下 可以采用数组来模拟实现 public class MyBlockingDeque {private String[] data null;private int head 0;private int tail 0;private int size 0;public MyBlockingDeque(int capacity) {data new String[capacity];} } 接下来是入队列的操作 public void put(String s) throws InterruptedException {synchronized (this) {while (size data.length) {this.wait();}data[tail] s;tail;if (tail data.length) {tail 0;}size;this.notify();} } 由于设计到变量的修改所以要加上锁这里调用wait和notify来模拟阻塞场景并且需要注意wait要使用while循环如果说被Interrupted打断了那么就会出现不可预料的错误 出队列也是相同的道理 public String take() throws InterruptedException { String ret ; synchronized (this) {while (size 0) {this.wait();}ret data[head];head;if (head data.length) {head 0;}size--;this.notify(); } return ret; } 3. 生产者消费者模型 生产者消费者模型是一种经典的多线程同步模型用于解决生产者和消费者之间的协作问题。在这个模型中生产者负责生产数据并将其放入缓冲区消费者负责从缓冲区中取出数据并进行处理。生产者和消费者之间通过缓冲区进行通信彼此之间不需要直接交互。这样可以降低生产者和消费者之间的耦合度提高系统的可维护性和可扩展性。 而阻塞队列可以当做上面的缓冲区 public class ThreadDemo21 {public static void main(String[] args) {BlockingDequeInteger blockingDeque new LinkedBlockingDeque(100);Thread t1 new Thread(()-{int i 1;while (true){try {blockingDeque.put(i);System.out.println(生产元素 i);i;Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});Thread t2 new Thread(()-{while (true){try {int i blockingDeque.take();System.out.println(消费元素 i);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.start();t2.start();} } 如果说把sleep的操作放到线程2会怎么样 线程一瞬间就把阻塞队列沾满了后面还是一个线程生产一个线程消费虽然打印出来的有偏差 生产者和消费者之间通过缓冲区进行通信彼此之间不需要直接交互。这样可以降低生产者和消费者之间的耦合度提高系统的可维护性和可扩展性。
http://www.hkea.cn/news/14451886/

相关文章:

  • 顺德网站优化公司做兼职的网站有哪些工作内容
  • 用自己的名字做网站域名免费家装设计效果图
  • 手机 pc网站开发价格兰州seo
  • 建设银行论坛网站企业网站的设计与实现
  • 免费做网站怎么做网站ppt制作模板免费下载
  • 德阳网站建设优化网站推广方案整理
  • 淘宝的好券网站怎么做马鞍山网站建设推广
  • 网站建设管理自查报告淘宝优惠网站怎么做
  • 新乡做网站哪家好怎么看网站是什么语言做的后台
  • 民宿设计网站大全厦门网站建站
  • 深圳做网站哪家好wordpress自带重定向
  • 工程建设科学技术奖申报网站电商网课
  • wordpress文章商品导购网站seo关键词排名查询
  • 贸易公司网站建设随意设计一个网站
  • 制作网站基本步骤用淘宝做公司网站
  • 实现网站计划书rails开发的网站开发
  • 深圳做企业网站个人网站模板html免费
  • 企业为什么要做手机网站个人社保缴费app下载
  • 怎么介绍自己做的电影网站网站建设必须要服务器吗
  • 广西城乡建设名网站代理网络游戏需要什么手续
  • 怎么做视频解析的网站html基础菜鸟教程
  • 传统网站与营销型网站做设计应该看哪些网站
  • 建建设网站的网站开发哪家公司口碑好
  • 基金管理公司司网站建设要求免费网站后台管理系统
  • 网站建设定制开发服务wordpress 中文 chm
  • 许昌北京网站建设专业做医院网站建设
  • 做排行的网站长春网架公司
  • 莱芜招聘的网站鞍山网站建设优化
  • 团购网站怎么做网站建设cach目录
  • 网站定制业务个人店铺logo