线程同步通信及其应用等相关内容及代码
来源:互联网 发布:淘宝闪电退货太恶心了 编辑:程序博客网 时间:2024/06/03 09:25
线程间的通信:
两个或两个以上的线程处理同一个资源,处理的动作是不一样的。
这样就需要将不同的动作代码放到不同的run方法中,run方法要封装到单独的类中。
同步中使用:
wait():让当前线程处于等待状态,释放cpu资源,同时释放锁。
notify():唤醒等待的线程,唤醒第一个
notifyAll():唤醒所以等待的线程。
object类的方法
wait():让当前线程处于等待状态,释放cpu资源,同时释放锁。
sleep():释放cpu资源,但是不释放锁。
多线程在开发中的应用
1.下载
2.聊天
实例,生产者和消费者。
分析:
生产者-消费者问题是多线程同步处理的典型问题
有一块生产者和消费者共享
的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品,这个过程可以无
休止的执行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产
品可取而终止。
线程B写一次,线程A读一次
在某个时候线程B运行速度比较快,在线程A未读取上一个数据之前,B就写了第二次数据
,造成数据遗漏。
在某个时候线程A运行速度比较快,它读完一次数据之后,线程B还没来得及写,线程A又
来读第二次。结果线程A读不到数据,导致运行出错。
线程B正在写数据时,线程A也来读取数据,这时可能线程B还没将数据写完,线程A将数
据读走,导致程序出错。
解决生产者消费者问题的方法
一种是采用某种机制保持生产者和消费者之间的同步(有较高的效率并且可控制性较好,
比较常用
)
一种是在生产者和消费者之间建立一个管道(由于管道缓冲区不易控制及被传输数据对象
不易封装等原因,比较少用
)
程的同步解决生产者-消费者问题
限制公共缓冲区不能被两个线程同时访问,需要使用互斥锁,即用synchronized来标识
同步资源。
但加了互斥锁以后有可能会造出死锁。这时需要wait()方法和notify()方法--当前线程
被阻塞并释放该对象的互斥锁。
生产者与消费者实例应用代码(修改前,不够简洁):
package com.hbsi;
//资源类
class Res {
String name;
String sex;
boolean b;
}
// 生产者类
class Input implements Runnable {
private Res r;
public Input(Res r) {
this.r = r;
}
int x = 0;
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (r) {
//判断是否需要生产
if(r.b)
try {
r.wait();//释放CPU资源同时释放锁
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (x == 0) {
r.name = "张三";
r.sex = "男";
} else {
r.name = "lisi";
r.sex = "nv";
}
r.b=true;
r.notify();
x = (x + 1) % 2;
}
}
}
}
// 消费者类
class Output implements Runnable {
private Res r;
public Output(Res r) {
this.r = r;
}
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (r) {
if(!r.b)
try {
r.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(r.name + "..." + r.sex);
r.b=false;
r.notify();
}
}
}
}
public class ThreadDemo4 {
public static void main(String[] args) {
Res t = new Res();
Input in = new Input(t);
Output out = new Output(t);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
生产者与消费者实例应用代码(修改后,更符合编程的要求):
package com.hbsi;
//对ThreadDemo4进行优化
class Res1 {
private String name;
private String sex;
private boolean flag;
public synchronized void set(String name, String sex) {
if (flag)
try {
wait();//相当于this.wait();锁
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.name = name;
this.sex = sex;
flag = true;
notify();
}
public synchronized void out() {
if (!flag)
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "...." + sex);
flag = false;
notify();
}
}
// 生产者类
class Input1 implements Runnable {
private Res1 r;
public Input1(Res1 r) {
this.r = r;
}
int x = 0;
public void run() {
while (true) {
if (x == 0) {
r.set("张三", "男");
} else {
r.set("lisi", "nv");
}
x = (x + 1) % 2;
}
}
}
// 消费者类
class Output1 implements Runnable {
private Res1 r;
public Output1(Res1 r) {
this.r = r;
}
public void run() {
while (true) {
r.out();
}
}
}
public class ThreadDemo5 {
public static void main(String[] args) {
Res1 t = new Res1();
Input1 in = new Input1(t);
Output1 out = new Output1(t);
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
t1.start();
t2.start();
}
}
- 线程同步通信及其应用等相关内容及代码
- 进程/线程同步及通信
- java 线程间通信同步代码块
- 多线程补充、多线程问题及处理、线程的同步及相关内容
- 进程,线程通信与同步及区别
- 进程,线程通信与同步及区别
- Linux下线程间通信及同步
- 线程、进程及其相关内容的完整总结
- 单片机代码保护及相关内容
- 第二~五节、线程同步、通信、死锁及线程控制
- 线程之间进程之间的通信方式及其代码实现
- GCD的定义及使用详解(同步异步、并发串行、线程间通信、延时执行、只执行一次代码)
- 线程及其通信
- 线程通信和同步
- 线程同步通信
- 同步,线程通信,lock
- 线程同步通信
- 线程之同步通信
- 一些有用的数论公式
- .NET截取指定长度汉字超出部分以"..."代替
- 把Thrift框架移植到Metro App
- 收集一些感觉不错的旅游圣地吧
- 埋藏
- 线程同步通信及其应用等相关内容及代码
- C与C++中的&问题
- 使用sort()方法实现数组排序
- android press 事件监测
- pc上修改jffs2
- 什么是ThreadLocal?
- Cygwin中VIM的设置 【转载】
- 设计模式C++实现(16)——状态模式
- 分享一下自己整理的pb常用函数