`

发送线程与接收线程 速率一致

 
阅读更多
package com.jbx.xiezuo;

/**
 * 采用信号量和同步方法使发送线程与接收线程同步运行。
 * 
 * @author Administrator
 *         value是共享变量,put()和get()方法都要对value进行操作。由于put()和get()方法针对同一个数据进行相反操作;
 *         当value为空时,put()方法可以赋值而get()方法不可以赋值,必须等待;
 *         反之,当value不为空时,get()方法可以取值,而put()方法不可以赋值,必须等待。
 *         因此,put()和get()方法必须以value是否为空值作为标记互斥地、交替地进行。
 * 
 */
public class BufferLock { // 加互斥锁的缓冲区
	private int value;
	private boolean isEmpty = true; // value是否为空的信号量

	public synchronized void put(int i) {
		while (!isEmpty)  // 当value不为空时,等待
			try {
				this.wait();
			} catch (InterruptedException e) {
				
			}
		
		value = i; // 当value为空时,value获得值
		isEmpty = false; // 设置value为不空状态
		notify(); // 唤醒其他等待线程
	}

	public synchronized int get() { // 同步方法
		while (isEmpty)  // 当value为空时等待
			try {
				this.wait();
			} catch (InterruptedException e) {
				
			}
		

		isEmpty = true; // 设置value为空状态,并返回值
		notify();
		return value;

	}

	public static void main(String[] args) {
		BufferLock buffer = new BufferLock();
		(new Sender(buffer)).start();
		(new Receiver(buffer)).start();
	}
}

class Sender extends Thread { // 发送线程类
	private BufferLock buffer; // 用于交换数据的共享变量

	public Sender(BufferLock buffer) { // 指定缓冲区
		this.buffer = buffer;
	}

	public void run() {
		for (int i = 1; i < 6; i++) { // 连续向缓冲区发送若干数据
			buffer.put(i);
			System.out.println("Sender put: " + i);
		}
	}
}

class Receiver extends Thread { // 接收线程类
	private BufferLock buffer;

	public Receiver(BufferLock buffer) {
		this.buffer = buffer;
	}

	public void run() {
		for (int i = 1; i < 6; i++) { // 连续从缓冲区接收若干数据
			System.out.println("\t\t   Receiver get:" + buffer.get());
		}
	}

}



运行结果:
Sender put: 1
Sender put: 2
   Receiver get:1
   Receiver get:2
Sender put: 3
   Receiver get:3
Sender put: 4
   Receiver get:4
Sender put: 5
   Receiver get:5
解析:
     其中,isEmpty是标记value是否为空的一个信号量,当value为空时,isEmpty值为true;当value不空时,isEmpty值为false。
    在put()方法中,先查看信号量的状态,如果是isEmpty值为true,表示value为空,可以对value赋值,之后唤醒一个等待接收线程;否则表示value不空,即value值未被取走,此时不能对value赋值,只能等待。
    在get()方法中,先查看信号量的状态,如果isEmpty值为true,表示value未赋值,此时取不到有效value值,只能等待;否则表示value不空,返回value值,并唤醒一个等待发送线程。
    两个线程分别调用put()和get()方法执行流程如图所示。



     运行结果,不同线程之间实现了同步传递数据。
注意:在互斥的put()和get()方法中,如果只有wait()方法而没有notify()方法,则线程死锁。
  • 大小: 63.5 KB
分享到:
评论

相关推荐

    基于UDP协议的多线程高速接收QT工程

    【标题】"基于UDP协议的多线程高速接收QT工程"揭示了这个项目的核心技术是使用UDP协议进行高速数据接收,并结合多线程技术来处理海量数据,且它是在QT框架下实现的。QT是一个流行的跨平台应用程序开发框架,特别适合...

    论文研究-多线程技术在条件接收系统中的应用 .pdf

    此外,本文还详细介绍了多线程设计思想在条件接收系统中的应用,并通过实际运行系统实例验证了其可行性。通过这些方法,多线程技术在条件接收系统中的应用不仅保证了实时性,同时也提高了系统效率和稳定性。 中国...

    多线程,多接收模式串口类 LsComm 之二_串口多线程_串口_多接收模式串口类LsComm_多线程.zip

    例如,一条线程负责发送数据,另一条线程负责接收数据,这样即使在接收数据时也可以发送新的数据,避免了串行操作可能造成的延迟。 其次,串口通信是一种常见的硬件接口,用于设备间的串行数据传输。它基于RS-232、...

    基于MFC 的Socket类的多线程文件传输

    例如,TCP协议的滑动窗口机制可以用来动态调整发送速率,以适应网络状况。 总的来说,"基于MFC的Socket类的多线程文件传输"涉及到的知识点包括: 1. MFC框架和CSocket类:理解MFC的类库结构,以及如何使用CSocket...

    Delphi 串口与多线程

    例如,在给定的代码片段中,可以看到多个与串口相关的控件和变量,如`MSCommIn`和`MSCommOut`,它们分别用于接收和发送数据。`cmbbxSerialIn`和`cmbbxSerialOut`用于选择串口设备,而`cmbbxBaudIn`和`cmbbxBaudOut`...

    自己实现的 ActiveMQ 多线程客户端 包含生产消息客户端和消费者消息客户端

    - **Amq_Producer_mt.cpp**:扩展了 Amq_Producer.cpp,增加了多线程支持,每个线程独立发送消息,提高消息发送速率。 - **Amq_Consumer.cpp**:消费者客户端的实现,负责接收和处理来自 ActiveMQ 服务器的消息。 ...

    多线程开发案例(TCP窗口协议)

    每个线程可以独立地执行特定的任务,例如在TCP协议实现中,一个线程可能负责接收数据,另一个线程则负责发送数据。 2. **TCP协议**: - TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输层协议...

    qt 线程池实现多线程下载

    通过学习和分析这些代码,开发者可以更好地理解和应用Qt的多线程与网络编程技术。 总结起来,Qt的线程池和网络模块为实现高效、可控的多线程HTTP下载提供了便利。通过合理设计和优化,我们可以创建一个既能充分利用...

    单线程文件下载源码,

    WinSock是Windows平台上的网络编程接口,提供了TCP/IP协议栈的功能,用于建立和维护网络连接,发送和接收数据。 5. **错误处理与异常安全**:在多线程环境中,错误处理尤为重要,因为线程可能会因各种原因失败。...

    主线程和工作线程相互之间的通信示例程序

    在多线程编程中,线程间的通信是一个关键的概念,特别是在复杂的系统中,主线程与工作线程的协作是确保程序高效、稳定运行的基础。本文将深入探讨标题和描述所提及的“主线程和工作线程相互之间的通信示例程序”,并...

    基于socket多线程图片传输程序

    为了实现这一功能,程序可能使用了某种计时机制,记录图片数据从发送到接收的时间,并根据图片大小计算传输速率。这通常涉及到时间戳的处理和数据统计,以便实时反馈给用户。 在具体实现上,VC环境提供了丰富的...

    多线程socket文件传输

    6. **确认与校验**:为了保证数据完整性,通常会在接收端进行校验,如计算MD5或CRC值,确保接收到的数据与发送的数据一致。 7. **关闭连接**:文件传输完成后,客户端和服务器端都需要关闭socket连接。 在这个项目...

    QT+UDP实时视频发送与接收.rar

    QT+UDP实时视频发送与接收是一个关于利用QT框架和UDP协议进行实时视频数据传输的项目。这个项目包含发送端和接收端两个独立的工程,旨在实现高效、低延迟的视频流传输。 首先,QT(Qt)是一个跨平台的应用程序开发...

    关于线程和tcp的模拟读写文件

    - **同步与互斥**:在多线程环境中,为了避免数据竞争和不一致性,需要使用锁、信号量等机制进行同步和互斥控制。 2. **TCP**: - **面向连接**:TCP是一种面向连接的传输层协议,它在数据传输前先建立连接,确保...

    .net webservice多线程上传 cs+bs

    3. 错误检测:检查文件完整性,如MD5校验,确保上传的文件与原文件一致。 4. 并发控制:服务端可能需要限制并发连接数,避免过载。 五、BS架构中的交互 1. JavaScript或AJAX:在浏览器端,使用JavaScript或AJAX异步...

    多线程端口通信小程序

    发送线程则可以在数据准备好后立即发送,无需等待接收线程完成操作。这样的设计提高了程序的响应性和实时性。 4. ** MulThreadMFC项目**: 根据提供的压缩包文件名,这个项目很可能是使用MFC库创建的一个多线程...

    bcb 多线程示例 MutilThread(生产者与消费者)

    然而,需要注意的是,线程可能在处理任务时无法立即停止,因此通常需要在线程类中实现一个循环,以便在接收到终止请求时能够优雅地结束。 最后,为了解决资源泄漏问题,每个线程在其`Execute`方法执行完毕后,应...

    PyQT多线程串口工程文件 PyCharm

    该库提供了打开、关闭串口,发送和接收数据,设置波特率、校验位、停止位等参数的功能。 **3. 多线程** 在GUI应用中,为了保持界面的响应性和流畅性,串口读写操作通常应在后台线程中执行,而不是主线程。Python的`...

    http多线程下载

    此外,这种技术还能根据网络状况动态调整每个线程的下载速率,以最大化整体性能。 断点续传是多线程下载中的另一个关键特性。它允许用户在下载过程中随时暂停,然后在稍后的时间点继续下载,而不会丢失已经下载的...

Global site tag (gtag.js) - Google Analytics