Java多线程间通信-解决安全问题、等待唤醒机制
/*
1.增加一个知识点
一个类怎么在所有的类中,让其它类来共同修改它的数据呢?
可以用单例设计模式
可以用静态
可以在其它类中做一个构造函数,接受同一个对象,这样就可以实现对象
2.状态选择
可以用数字0 1 判断
可以用bool
注意变量的范围即可
3.加了同步后,还是有安全怎么办?
想前提! 1. 两个及以上线程(同步的) 2.操作公用资源 3.要用同一锁
*/
/*
线程间通讯:
其实就是多个线程在操作同一个资源,
但是操作的动作不同。
*/
/*
1.为什么会出现安全问题?
就是不满足前提呗
2.我们还没有了解到线程的本质
1.线程的执行时互相争抢执行权的
2.如果没有同步代码块的话,就会对数据进行胡乱修改,有可能修改到一半,另一个线程进来,有可能修改好几次,等等,甚至还会无视条件
3.即便有了同步代码块,也不能保证代码是按次序相互执行,因为,第一个线程执行完之后,还会参与下一次的争抢当中来,拥有相同的争抢概率
所以就出现同步中的不同步状况,这时候就要用到唤醒
4.其实程序就是一个逻辑判断问题,就是看有没有数据
*/
/*五种状态之一的等待
1.是Thread从上帝那里继承来的
2.而且这个函数是抛了异常的,根据异常的格式,要try和catch
3.唤醒也是继承上帝的
4.使用的时候,直接用对象点出来就可以
5.这样很容易区分,也造成为什么要把这两个函数写在上帝里面的原因,锁是任意类型的,什么对象都可以
*/
class Res /*定义一个类,里面封装好数据成员,用来去调用*/
{
String name;
String sex;
boolean flag = false; /*用来判断是否已经存入数据,封装好用来调用*/
}
class Input implements Runnable
{
private Res r ;
Input(Res r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r) /*只能让一个线程进来,而且输入的先进来,输出的就不给进了,这样就满足了前提,有两个线程,同一锁,公共资源*/
{
if(r.flag) /*真,冻结*/
try{r.wait();}catch(Exception e){} /*线程池,等待线程都在线程池当中,唤醒的是什么,唤醒的都是线程池当中的线程*/
if(x==0)
{
r.name="mike"; /*赋值*/
r.sex="man";
}
else
{
r.name="丽丽";
r.sex = "女女女女女";
}
x = (x+1)%2; /*转换性别*/
r.flag = true;
r.notify(); /*有就唤醒,没有就不唤醒,按顺序来自然就不需要这个,唤醒的是另一个线程*/
}
}
}
}
class Output implements Runnable
{
private Res r ; /*对象数据成员*/
Output(Res r)
{
this.r = r; /*传递对象进来*/
}
public void run()
{
while(true)
{
synchronized(r) /*放的是对象*/
{
if(!r.flag)
try{r.wait();}catch(Exception e){}
System.out.println(r.name+"...."+r.sex); /*删除*/
r.flag = false;
r.notify(); /*唤醒输入线程*/
}
}
}
}
class InputOutputDemo
{
public static void main(String[] args)
{
Res r = new Res(); /*封装好的类,将会当作参数,传递给其它类*/
Input in = new Input(r); /*实现多线程类的对象*/
Output out = new Output(r);
Thread t1 = new Thread(in); /*开启线程,把实现线程的对象放进来*/
Thread t2 = new Thread(out);
t1.start(); /*开启线程,调用run函数*/
t2.start();
}
}
//notifyAll();
/*
wait:
notify();
notifyAll();
都使用在同步中,因为要对持有监视器(锁)的线程操作。
所以要使用在同步中,因为只有同步才具有锁。
为什么这些操作线程的方法要定义Object类中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁,
只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。
不可以对不同锁中的线程进行唤醒。
也就是说,等待和唤醒必须是同一个锁。
而锁可以是任意对象,所以可以被任意对象调用的方法定义Object类中。
*/
代码优化:
/*
线程间通讯:
其实就是多个线程在操作同一个资源,
但是操作的动作不同。
*/
class Res
{
private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name,String sex)
{
if(flag)
try{this.wait();}catch(Exception e){} /*记住,加同步的是共同操作的数据,不是定义数据,是会变动的数据*/
this.name = name;
this.sex = sex;
flag = true;
this.notify(); /*this代表同步函数的锁,也代表当前对象*/
}
public synchronized void out()
{
if(!flag)
try{this.wait();}catch(Exception e){}
System.out.println(name+"........"+sex);
flag = false;
this.notify();
}
}
class Input implements Runnable
{
private Res r ; /*用来接收同一个对象*/
Input(Res r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
if(x==0)
r.set("mike","man"); /*这个函数已经是同步函数了*/
else
r.set("丽丽","女女女女女");
x = (x+1)%2;
}
}
}
class Output implements Runnable
{
private Res r ;
Output(Res r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out(); /*不断输出*/
}
}
}
class InputOutputDemo2
{
public static void main(String[] args)
{
Res r = new Res();
new Thread(new Input(r)).start(); /*全部使用无名对象,优化代码*/
new Thread(new Output(r)).start();
/*
Input in = new Input(r);
Output out = new Output(r);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
*/
}
}
Java多线程间通信-解决安全问题、等待唤醒机制的更多相关文章
- Java 多线程间通信
JDK 1.5 以后, 将同步和锁封装成了对象, 并将操作锁的隐式方法定义到了该对象中, 将隐式动作变成了显示动作. Lock 接口 Lock 接口, 位于 java.util.concurrent. ...
- Java 线程之间的通讯,等待唤醒机制
public class ThreadNotifySample { public static void main(String[] args) { // Res res = new Res(); / ...
- java 多线程间通信(二)
传统的线程通信 Object提供了三个方法wait(), notify(), notifyAll()在线程之间进行通信,以此来解决线程间执行顺序等问题. wait():释放当前线程的同步监视控制器,并 ...
- java 多线程间通信(一)
synchronized同步 package com.test7; public class Run { public class MyObject { private int a; public M ...
- java 中多线程之间的通讯之等待唤醒机制
wait notify () nitifyAll () 都使用在同步中,因为要对持有监视器(锁)的线程操作 所以要使用在同步中,因为只有同步才具有锁 为什么这些操作线程的方法要定义object类中呢 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第4节 等待唤醒机制_1_线程状态概述
Thread中有个嵌套类 它描述了线程的状态 线程状态的图 Object类中的Wait方法和notify方法
- java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)
*java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...
- java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)
1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以 ...
- JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制
JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...
随机推荐
- SpringMVC(三)
今天是学习Spring的第四天,今天终于又把Spring+SpringMVC+Mybatis(SSM)高了一遍,这次运行的代码和配置和昨天的不一样,今天运行的很成功. 主要学习的一点就是我今天使用的是 ...
- MSSQLSERVER- CharIndex的妙用,找出有妙用
CharIndex 1:CharIndex语法: CharIndex(expression1,expression2[,start_location]) 2:参数 expression1 一个表达式, ...
- sudo: /etc/sudoers is mode 0640, should be 0440解决办法
ubuntu或者CentOS中,/etc/sudoer 的权限为 0440时才能正常使用,否则sudo命令就不能正常使用.出现类似:sudo: /etc/sudoers is mode 0640, s ...
- C++容器类对象函数參数问题
总之中的一个句话:容器类对象作为函数參数,与整数类型作为函数參数的传递特性同样. 验证程序 #include "stdafx.h" #include <iostream> ...
- bmp to jpg
uses Jpeg; function BMPtoJPG(var BMPpic, JPGpic: string): boolean;var Bitmap: TBitmap; JpegImg: TJ ...
- 《Java并发编程实战》第十五章 原子变量与非堵塞同步机制 读书笔记
一.锁的劣势 锁定后假设未释放.再次请求锁时会造成堵塞.多线程调度通常遇到堵塞会进行上下文切换,造成很多其它的开销. 在挂起与恢复线程等过程中存在着非常大的开销,而且通常存在着较长时间的中断. 锁可能 ...
- "无法启动程序,因为计算机中丢失*.dll” 运行exe错误解决方法
笔者把编译生成的win32 Release exe文件复制到另外一台电脑上,却发现程序不能运行,报错如下: 报错提示缺失动态链接库pcl_common_release.dll,那为什么在编译生成的电脑 ...
- 如何编写程序设置Android来电铃声
我们在拿到新手机后通常会为其设置来年铃声,那么怎样通过代码来设置Android来电铃声,本文就为大家实例讲解下. 1.如果读到的是音频文件路径,需要先将音乐文件插入到多媒体库. Java代码 //设置 ...
- 教你如何选择Android游戏引擎
我们进行Android游戏开发时选择游戏引擎是必须的,但是该如何选择呢?哪个Android游戏引擎更加适合自己呢?本文就提供了三个游戏引擎的对比说明,阐述了它们各自的特点,为大家选择引擎提供了参照. ...
- Linux性能及调优指南(翻译)之Linux内存架构
http://blog.csdn.net/ljianhui/article/details/46734115