本节开始线程间通信:

  1. 使用wait/notify实现线程间通信
  2. 生产者/消费者模式的实现
  3. 方法join的使用
  4. ThreadLocal类的使用

可以通过使用 sleep() 结合 while(true) 死循环来实现线程间的通信

通过使用while(true){  if(条件)  } 来检查某个数据,满足条件时结束循环,线程会处在不断运行的状态,会浪费CPU资源

wait/notify 机制应运而生(等待通知机制)

方法wait()的作用是使当前执行代码的线程等待,将当前线程放置到“预执行队列”中,并且在wait所在的代码行处停止执行,知道接收到通知或者被中断为止。在调用wait之前,线程必须获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait方法。执行wait方法之后,当前线程会释放锁。

方法notify也要在同步方法或者同步块中使用,即在调用前必须获得对象级别的锁。notif会随机挑选一个wait状态的线程,对其发送notify通知,并使他等待获得该对象的对象锁。在执行notify方法之后,当前线程不会立马释放掉该对象锁,呈wait状态的线程也不能马上获得该对象锁,要等待执行notify方法的线程将所有程序执行完也就是退出synchronized代码块后,当前线程才会释放锁。

public class Mythread1 extends Thread {
private Object lock;
public Mythread1 (Object lock){
super();
this.lock = lock;
} @Override
public void run(){
try{
synchronized (lock){
System.out.println("开始 wait time "+System.currentTimeMillis());
lock.wait();
System.out.println("结束 wait time "+System.currentTimeMillis());
}
}catch (InterruptedException e){
e.printStackTrace();
}
} } public class MyThread2 extends Thread {
private Object lock; public MyThread2(Object lock) {
super();
this.lock = lock;
} @Override
public void run() { synchronized (lock) {
System.out.println("开始 notify time " + System.currentTimeMillis());
lock.notify();
System.out.println("结束 notify time " + System.currentTimeMillis());
} }
} public class Test {
public static void main(String[] args) {
try{
Object lock = new Object();
Mythread1 t1 = new Mythread1(lock);
t1.start();
Thread.sleep(3000);
MyThread2 t2 = new MyThread2(lock);
t2.start();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
开始  wait time 1575421393700
开始 notify time 1575421396701
结束 notify time 1575421396702
结束 wait time 1575421396703
public class ThreadA extends Thread{
private MyList list; public ThreadA(MyList list){
super();
this.list = list;
} @Override
public void run(){
try{
synchronized(list){
for(int i =0; i<10; i++){
list.add();
if(list.size() == 5){
System.out.println("已发出通知。");
list.notify();
}
System.out.println("add item "+(i+1)+"...");
Thread.sleep(1000);
}
} }catch(InterruptedException e){
e.printStackTrace();
}
}
} public class ThreadB extends Thread{
private MyList list; public ThreadB(MyList list){
super();
this.list = list;
} @Override
public void run(){
try{
synchronized(list){
if(list.size() != 5){
System.out.println("wait begin="+System.currentTimeMillis());
list.wait();
System.out.println("wait end="+System.currentTimeMillis());
}
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
} public class RunDemo { public static void main(String[] args) {
MyList run = new MyList();
try {
ThreadB tB =new ThreadB(run);
tB.setName("B");
tB.start();
Thread.sleep(500);
ThreadA tA= new ThreadA(run);
tA.setName("A");
tA.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} wait begin=1516089526512
add item 1...
add item 2...
add item 3...
add item 4...
已发出通知。
add item 5...
add item 6...
add item 7...
add item 8...
add item 9...
add item 10...
wait end=1516089537079

关键字synchronized可以将任何一个Object对象作为同步对象来看待,而Java为每一个Object都实现来wait和notify方法,它们必须用在被synchronized同步的Object临界区内。

方法wait锁释放与方法notify锁不释放,notify要在线程把程序所有代码执行完毕后才释放

interrupt方法不能在线程处于wait状态时使用,会报错

方法wait(long)

带一个参数的wait(long)方法的功能是等待某一时间内是否有线程对锁进行唤醒,如果超过这个时间则自动唤醒

java多线程学习笔记(八)的更多相关文章

  1. Java IO学习笔记八:Netty入门

    作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...

  2. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  3. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...

  4. Java多线程学习笔记(一)——多线程实现和安全问题

    1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...

  5. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

  6. Java多线程学习笔记--生产消费者模式

    实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...

  7. java 多线程学习笔记

    这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...

  8. Java 多线程学习笔记:生产者消费者问题

    前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...

  9. Java多线程学习(八)线程池与Executor 框架

    目录 历史优质文章推荐: 目录: 一 使用线程池的好处 二 Executor 框架 2.1 简介 2.2 Executor 框架结构(主要由三大部分组成) 2.3 Executor 框架的使用示意图 ...

  10. java多线程学习笔记(三)

    java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...

随机推荐

  1. Codeforces Round #460 (Div. 2) B Perfect Number(二分+数位dp)

    题目传送门 B. Perfect Number time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  2. CF208E Blood Cousins

    Blood Cousins 题目描述 小C喜欢研究族谱,这一天小C拿到了一整张族谱. 小C先要定义一下k-祖先. x的1-祖先指的是x的父亲 x的k-祖先指的是x的(k-1)-祖先的父亲 小C接下来要 ...

  3. 微信、qq网页二次分享

    二次分享是指,在APP或者浏览器分享到微信或者qq,然后从微信或者qq再分享到别的平台.如果不处理,再次分享出去的图片或者标题就不会显示,对用户非常不友好. 一.微信二次分享 官方接入文档:https ...

  4. 07.Linux-CentOS系统库文件libaudit.so.1丢失问题

    问题:缺少共享库文件sudo: error while loading shared libraries: libaudit.so.1: cannot open shared object file: ...

  5. win10 护眼

  6. Vue的计算属性缓存和method的区别在哪?

    一.先看一个例子 <div id="example"> {{ message.split('').reverse().join('') }} </div> ...

  7. 洛谷3605 Promotion Counting

    线段树合并都是蓝题了嘛 我可能和时代脱轨了emm... 直接离散化然后合并就好啦w 生病了真难受QAQ //Love and Freedom. #include<cstdio> #incl ...

  8. pycharm html 注释

    修改方式:如图修改成值None以后,command+/快捷键,html注释的符号就是<!-- 注释内容 -->:为Jinja2的时候,注释符号就是{# 注释内容 #} 修改成None时,H ...

  9. 百度小程序-swiper组件

    .swan <!-- 轮播图S --> <view class="swiper-box"> <swiper class="banner&qu ...

  10. 一款易用、高可定制的vue翻页组件

    一款易用.高可定制的vue翻页组件 在线体验:pages.cixi518.com 使用 npm i vo-pages --save vo-pages组件父元素必须设置固定高度并填写属性overflow ...