博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
猿来绘Java-35-线程的同步(生产者和消费者问题)
阅读量:2095 次
发布时间:2019-04-29

本文共 2336 字,大约阅读时间需要 7 分钟。

 

1.同步与互斥的理解

首先来介绍下进程的同步与互斥

进程的同步:一个进程的执行,依赖于另一个进程的运行的消息, 消息到达才能继续执行。我们把异步环境下的一组并发进程因直接制约而互相发送消息、进行互相合作、互相等待,使得各进程按一定的顺序执行的过程称为进程间的同步。在多道程序环境下,进程是并发执行的,不同进程之间存在着不同的相互制约关系

进程的互斥:两个或两个以上的进程,不能同时进入关于同一组共享变量的临界区域,否则可能发生与时间有关的错误,这种现象被称作进程互斥,也就是说,一个进程正在访问临界资源,另一个要访问该资源的进程必须等待。

概念比较抽象,举个例子,经典的生产者和消费者问题

多个生产者共同生成产品,它们将产品放入仓库(临界区),多个消费者取出产品,对产品进行消费。这里的多个生产者,某一时刻只允许一个生产者将产品放入临界区,多个生产者之间是互斥关系。生产者生产了产品并放入仓库, 消费者才能取出产品进行消费,这里的生产者和消费者是同步关系。

同步与互斥不是一对反义词,互斥的反义词应该是共享。

同步反应的是一种协作关系。

如果做过LinuxC系统编程,真正写过PV操作、信号量、互斥锁等相关开发,相信你比较清楚以上概念了。Java中的同步以及同步的实现封装了,我个人感觉实现的并不好。

 

2.线程的安全问题

多个线程执行的不确定性引起执行结果的不稳定

多个线程对数据的共享,会造成操作的不完整性,会破坏数据。

 

多线程处理缓冲区的消息时,存在重复处理和错误处理问题,比如重复处理消息100, 错误处理了消息0或-1等。

 

//ProcessMessageTest.javapackage com.ylaihui.thread;class ProcessMessage implements Runnable{    private int message = 100;    @Override    public void run() {        while(true) {            if(message > 0) {                System.out.println("process message: " + message);                message--;            }else                break;        }    }}public class ProcessMessageTest {    public static void main(String[] args) {        ProcessMessage p = new ProcessMessage();        Thread t1 = new Thread(p);        Thread t2 = new Thread(p);        Thread t3 = new Thread(p);        t1.start();        t2.start();        t3.start();    }}

 

3. 解决线程安全问题

synchronized(同步监视器){//需要被同步的代码}

说明:

1.操作共享数据的代码,即为需要被同步的代码

2.共享数据:多个线程共同操作的变量

3.同步监视器,俗称:锁。任何一个类的对象,都可以充当锁,但是多个线程必须要共用同一把锁。

通过实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。

使用继承Thread创建多线程的方式,可以使用继承类的Xxx.class方式充当同步监视器

代码示例: 多线程同时处理100条消息

//ThreadSynchronizedBlock.javapackage com.ylaihui.thread;class ProcessMessage1 implements Runnable{    private int message = 100;    Object obj = new Object();    @Override    public void run() {//        synchronized(obj){        synchronized(this){            while(true){                if(message > 0){                    System.out.println("process message: "+ message);                    message--;                }else                    break;            }        }    }}public class ThreadSynchronizedBlock {    public static void main(String[] args) {        ProcessMessage1 p = new ProcessMessage1();        Thread t1 = new Thread(p);        Thread t2 = new Thread(p);        Thread t3 = new Thread(p);        t1.start();        t2.start();        t3.start();    }}

 

 

 

 

 

 

 

 

 

转载地址:http://ltuhf.baihongyu.com/

你可能感兴趣的文章
PCA 的数学原理和可视化效果
查看>>
机器学习中常用评估指标汇总
查看>>
什么是 ROC AUC
查看>>
Bagging 简述
查看>>
详解 Stacking 的 python 实现
查看>>
简述极大似然估计
查看>>
用线性判别分析 LDA 降维
查看>>
用 Doc2Vec 得到文档/段落/句子的向量表达
查看>>
使聊天机器人具有个性
查看>>
使聊天机器人的对话更有营养
查看>>
一个 tflearn 情感分析小例子
查看>>
attention 机制入门
查看>>
手把手用 IntelliJ IDEA 和 SBT 创建 scala 项目
查看>>
GAN 的 keras 实现
查看>>
AI 在 marketing 上的应用
查看>>
Logistic regression 为什么用 sigmoid ?
查看>>
Logistic Regression 为什么用极大似然函数
查看>>
为什么在优化算法中使用指数加权平均
查看>>
Java集合详解1:一文读懂ArrayList,Vector与Stack使用方法和实现原理
查看>>
Java集合详解2:一文读懂Queue和LinkedList
查看>>