java多线程学习笔记(八)
本节开始线程间通信:
- 使用wait/notify实现线程间通信
- 生产者/消费者模式的实现
- 方法join的使用
- 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多线程学习笔记(八)的更多相关文章
- Java IO学习笔记八:Netty入门
作者:Grey 原文地址:Java IO学习笔记八:Netty入门 多路复用多线程方式还是有点麻烦,Netty帮我们做了封装,大大简化了编码的复杂度,接下来熟悉一下netty的基本使用. Netty+ ...
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- Java多线程学习笔记--生产消费者模式
实际开发中,我们经常会接触到生产消费者模型,如:Android的Looper相应handler处理UI操作,Socket通信的响应过程.数据缓冲区在文件读写应用等.强大的模型框架,鉴于本人水平有限目前 ...
- java 多线程学习笔记
这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...
- Java 多线程学习笔记:生产者消费者问题
前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...
- Java多线程学习(八)线程池与Executor 框架
目录 历史优质文章推荐: 目录: 一 使用线程池的好处 二 Executor 框架 2.1 简介 2.2 Executor 框架结构(主要由三大部分组成) 2.3 Executor 框架的使用示意图 ...
- java多线程学习笔记(三)
java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...
随机推荐
- Uncaught TypeError: Cannot set property onclick' of null
如果出现以上问题,只需要把<script src="xxx.js"></script> 移动到最后,</body>的前面;
- SVN合并主干分支的方法
第一步 第二步 第三步 第四步
- [fw]linux 下如何查看和踢除正在登陆的其它用户
linux 下如何查看和踢除正在登陆的其它用户 Posted on 2011/09/01 如何在linux下查看当前登录的用户,并且踢掉你认为应该踢掉的用户?请使用who这个命令来查看当前正在登录 ...
- CodeChef 3-Palindromes(Manacher+dp)
3-Palindromes Problem code: PALIN3 Submit All Submissions All submissions for this problem are ...
- UVAlive 6763 Modified LCS
LCS stands for longest common subsequence, and it is a well known problem. A sequence in thisproblem ...
- 【接口工具】接口抓包工具之Charles
上篇我们讲了Fiddler,Fiddler是用C#开发的,所以Fiddler不能在Mac系统中运行,没办法直接用Fiddler来截获MAC系统中的HTTP/HTTPS, Mac 用户怎么办呢? 1.F ...
- css样式表的引入方式
一般来说,css 有两种样式表的引入方式,在这里我记录一下,比较这两种引入方式的区别: <link rel="stylesheet" type="text/css& ...
- C中对整数的大端对齐与小端对齐的理解
示例 /* 大端与小端对齐 说明: 1.对于arm, intel这种x86架构的复杂指令cpu,整数在内存中是 倒着存放的,低地址放低位,高地址放高位,称之为小端对齐 2.对于linux服务器的cpu ...
- xcode 5.0 连接svn error -(NSURLErrorDomain error -1012)
xcode 5.0连接 svn server, check out时出现如下error : The operation couldn’t be completed. (NSURLErrorDomain ...
- python常用函数 J
(1)join(iterable)/(2) join(str, str) (1)join()连接字符串数组.(2)os.path.join()将多个路径组合后返回. 例子: