Java学习之线程间通信(双线程)
线程间通讯:多个线程在处理同一资源,但是任务不同
练习一:双线程出现线程安全问题,需要使用同步,思考同步代码添加位置
需求:银行账户存钱,显示谁在账户存钱了,存了多少钱
分析:
操作同一银行账户
两个不同的操作,一个是存,一个是显示
这个两个操作可以同时执行
代码:
class Bank
{
String name;//存钱人名
int amount; //无论是存还是取应该都是银行的动作
void put(String name,int amount)
{
this.name=name;
this.amount=amount;
} void take()
{
System.out.println(this.name+"---"+this.amount);
}
}
//定义对象实现Runnable,设置线程任务
class Input implements Runnable
{
private Bank b;
//使用构造函数保证存钱和显示同一资源
public Input(Bank b)
{
this.b=b;
}
public void run()
{
int x=0;
while(true)
{
if(x==0)
{
b.put("张三",100);
}
else
{
b.put("lisi",200);
}
//0与1之间切换可使用求2的余数
x=(x+1)%2;
}
}
} //定义对象实现Runnable,设置线程任务
class Output implements Runnable
{
private Bank b;
//使用构造函数保证存钱和显示同一资源
public Output(Bank b)
{
this.b=b;
}
public void run()
{
while(true)
{
b.take();
}
}
} class ThreadDemo
{
public static void main (String[] args)
{
//同一资源
Bank b=new Bank(); Input in=new Input(b);
Output out=new Output(b); //
Thread t1=new Thread(in);
Thread t2=new Thread(out); t1.start();
t2.start();
}
}
结果:

出现线程安全,为什么呢?
分析:

解决方法:添加同步(synchronized),同步要添加到什么位置?
添加同步锁的原则:有共享数据被操作的代码上,且同步锁对象要相同(同步方法的同步锁为,此类的对象(this))
代码:
class Bank
{
String name;//存钱人名
int amount; //同步方法的同步锁为,此类的对象(this)
synchronized void put(String name,int amount)
{
this.name=name;
this.amount=amount;
} synchronized void take()
{
System.out.println(this.name+"---"+this.amount);
}
}
结果出现的效果与预想结果不同,预想结果是存一笔,显示一笔:

结果分析:

接下来,想法是:在t1中执行完成后就让t2执行
具体做法:
1、使用一个共享数据(flag)记录t1是否已执行
2、已执行就让t1等待(原因:防止t1再次获取CPU执行权),让t2执行
3、t2执行完成,t2等待,把t1设置成未执行状态(让t1获取CPU执行资格)
class Bank
{
private String name;
private int amount;
private boolean flag=false; synchronized void put(String name,int amount)
{
//1、判断线程是否已执行,防止t1线程多次获取CUP执行权
if(flag)
try{this.wait();}catch(InterruptedException e){}//wait()方法,将线程存放在阻塞线程池中,释放CUP执行权和释放同步锁 this.name=name;
this.amount=amount;
//已执行赋值
this.flag = true;
//唤醒阻塞线程池中的任意一个线程,获取CUP执行资格
this.notify();
} synchronized void take()
{
if(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(this.name+"---"+this.amount); this.flag = false;
this.notify();
}
}
结果:

Java学习之线程间通信(双线程)的更多相关文章
- 【原】iOS多线程之线程间通信和线程互斥
线程间通信 1> 线程间通信分为两种 主线程进入子线程(前面的方法都可以) 子线程回到主线程 2> 返回主线程 3> 代码 这个案例的思路是:当我触摸屏幕时,会在子线程加载图片,然后 ...
- Java 里如何实现线程间通信
正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点:thread.join(), object.w ...
- Java 如何实现线程间通信
正常情况下,每个子线程完成各自的任务就可以结束了.不过有的时候,我们希望多个线程协同工作来完成某个任务,这时就涉及到了线程间通信了. 本文涉及到的知识点: thread.join(), object. ...
- Java多线程学习(五)线程间通信知识点补充
系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...
- 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题
调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...
- Java学习:线程间通信
线程间通信 概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同重点:有效的利用资源 分析:需要那些类 1 资源类:包子类 设置包子的属性 包子的状态:有true 没有false 2 ...
- Java多线程编程(6)--线程间通信(下)
因为本文的内容大部分是以生产者/消费者模式来进行讲解和举例的,所以在开始学习本文介绍的几种线程间的通信方式之前,我们先来熟悉一下生产者/消费者模式. 在实际的软件开发过程中,经常会碰到如下场景 ...
- java线程间通信:一个小Demo完全搞懂
版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程系列文章只是自己知识的总结梳理,都是最基础的玩意,已经掌握熟练的可以绕过. 一.从一个小Demo说起 上篇我们聊到了Java多线程的同步 ...
- java多线程与线程间通信
转自(http://blog.csdn.net/jerrying0203/article/details/45563947) 本文学习并总结java多线程与线程间通信的原理和方法,内容涉及java线程 ...
- Java多线程——线程间通信
Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...
随机推荐
- 图解Http阅读笔记(二)
简单的HTTP协议 HTTP是一种不保存状态,即无状态(stateless)协议.HTTP 协议自身不对请求和响应之间的通信状态进行保存.也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都不 ...
- 简单谈谈Netty的高性能之道
传统RPC 调用性能差的三宗罪 网络传输方式问题:传统的RPC 框架或者基于RMI 等方式的远程服务(过程)调用采用了同步阻塞IO,当客户端的并发压力或者网络时延增大之后,同步阻塞IO 会由于频繁的w ...
- 基于各种基础数据结构的SPFA和各种优化
一.基于各种数据结构的SPFA 以下各个数据均为不卡SPFA的最短路模板:P3371 [模板]单源最短路径(弱化版)的测试时间 1.STL队列:用时: 1106ms / 内存: 8496KB #inc ...
- 获取Linux内核未导出符号的几种方式
从Linux内核的2.6某个版本开始,内核引入了导出符号的机制.只有在内核中使用EXPORT_SYMBOL或EXPORT_SYMBOL_GPL导出的符号才能在内核模块中直接使用.然而,内核并没有导出所 ...
- mySql | Error: ER_DATA_TOO_LONG: Data too long for column 'base_info' at row 1
问题描述:执行insert语句报以下错误 原因:数据库表,该字段在设计的时候长度过小,新插入的数据过长,会提示以上错误! 解决办法:修改表中该字段的长度限定.
- tensorflow的reshape操作tf.reshape()
在处理图像数据的时候总会遇到输入图像的维数不符合的情况,此时tensorflow中reshape()就很好的解决了这个问题. 更为详细的可以参考官方文档说明: numpy.reshape reshap ...
- resolver - 解析器(resolver) 配置文件
总览 (SYNOPSIS) /etc/resolv.conf 描述 (DESCRIPTION) 解析器(resolver) 是 C 函数库 中 的 一组 例程, 用于 访问 Internet 域名系统 ...
- EXCUTE JAVAScript点击事件
# Execute Javascript document.getElementsByClassName('chooseFile')[${index}].arguments[0].click(); # ...
- OpenCV图像数据字节对齐
目录 1. IplImage的data字段,是char*类型,是4字节对齐. 2. 手动创建的Mat通常是没有字节对齐的 3. 从IplImage转过来的Mat,是字节对齐的 4. 总结 图像数据是否 ...
- Altium Designer 19 单层显示
PCB视图下,按快捷键L 弹出对话框 选择 view options 选项卡 Single Layer Mode 点击为on 快捷键为Shift + s