`
yixiaodiguo
  • 浏览: 3011 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

线程通讯和同步的两种实现方法

    博客分类:
  • java
 
阅读更多

同步和通讯两个方法实现:

  1. 一种是利用synchronized标示,利用继承的object类中的wait()和notify()或者notifyall()唤醒方法。synchronized可以声明方法,也可以用来标记某段代码。用来标记某段代码时的用法是:synchronized(){}。
    package thread;
    
    public class ThreadTimes {
    
    	/**
    	 * @param args
    	 * @throws InterruptedException 
    	 */
    	public static void main(String[] args) throws InterruptedException {
    		ThreadTimes tt = new ThreadTimes();
    		final Bussiness bussiness = tt.new Bussiness();
    		new Thread(){
    			@Override
    			public void run() {
    				for (int i = 0; i < 50; i++) {
    					try {
    						bussiness.sub(i);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}.start();
    		
    		for (int i = 0; i < 50; i++) {
    			bussiness.main2(i);
    		}
    	}
    	
    	class Bussiness{
    		boolean isSub = true;
    		public synchronized void sub(int i) throws InterruptedException{
    			while(!isSub){
    				this.wait();
    			}
    			for (int j = 0; j < 10; j++) {
    				System.out.println("sub time "+j+" of "+ i);
    			}
    			isSub = false;
    			this.notify();
    		}
    		
    		public synchronized void main2(int i) throws InterruptedException{
    			while(isSub){
    				this.wait();
    			}
    			for (int j = 0; j < 100; j++) {
    				System.out.println("mian time "+j+" of "+ i);
    			}
    			isSub = true;
    			this.notify();
    		}
    	}
    
    }
    
     
  2. 另外一种是加锁,生成锁的对象的方法是:private static Lock lock = new ReentrantLock();Lock是一个接口,而Reentrantlock是一个实现的类。构造方法有:ReentrantLock()和ReentrantLock(fair:boolean)两种。其中第二种传递的是一个boolean值的参数,当设置为true时系统会按照等待的先后时间让线程活得锁,但是效率和性能不如默认值的好,但是同时也可以避免资源匮乏。    通讯方面是利用锁生成Condition对象,然后调用await()和signal()或者signalall()。下面是实现的存款和取款的小程序。第一种实现的方法是lock加condition:

      作为一个示例,假定有一个绑定的缓冲区,它支持 puttake 方法。如果试图在空的缓冲区上执行 take 操作,则在某一个项变得可用之前,线程将一直阻塞;如果试图在满的缓冲区上执行 put 操作,则在有空间变得可用之前,线程将一直阻塞。我们喜欢在单独的等待 set 中保存 put 线程和 take 线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程。可以使用两个 Condition 实例来做到这一点

package thread;

import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ProducerConsumer {

	private static Buffer buffer = new Buffer();

	public static void main(String[] args) {
		ExecutorService executor = Executors.newCachedThreadPool();
		executor.execute(new ProduceTask());
		executor.execute(new ConsumerTask());
		executor.shutdown();

	}

	private static class ProduceTask implements Runnable {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				int i = 1;
				while (true) {
					System.out.println("producer write: " + i);
					buffer.write(i++);
					Thread.sleep((int) (Math.random() * 10000));
				}

			} catch (Exception ex) {
				ex.printStackTrace();
			}

		}

	}

	private static class ConsumerTask implements Runnable {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				while (true) {
					System.out
							.println("\t\t\tConsumer reads: " + buffer.read());
					Thread.sleep((int) (Math.random() * 10000));
				}
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}

	private static class Buffer {
		private static final int size = 2;
		private LinkedList<Integer> queue = new LinkedList<Integer>();

		private Lock lock = new ReentrantLock();

		private Condition notFull = lock.newCondition();
		private Condition notEmpty = lock.newCondition();

		public void write(int value) {
			lock.lock();
			try {
				while (queue.size() == size) {
					System.out.println("wait for notFull condition");
					notFull.await();
				}

				// queue.add(value);
				queue.offer(value);
				notEmpty.signal();

			} catch (Exception ex) {
				ex.printStackTrace();
			} finally {
				lock.unlock();
			}
		}

		public int read() {
			int value = 0;
			lock.lock();
			try {
				while (queue.size() == 0) {
					System.out.println("wait for notEmpty condition");
					notEmpty.await();
				}

				value = queue.remove();
				notFull.signal();

			} catch (Exception ex) {
				ex.printStackTrace();
			} finally {
				lock.unlock();

			}
			return value;

		}

	}

}

 

分享到:
评论

相关推荐

    多线程同步和通讯完整示例

    synchronized关键字提供了基本的线程同步,而wait-notify机制和Lock接口则提供了更高级的线程通讯和控制手段。在实际开发中,根据具体需求选择合适的同步策略,可以提高程序的效率和正确性。通过学习和实践...

    同步异步多线程SOCKET通讯

    这种方式易于理解和实现,但可能会遇到“线程饥饿”问题,即某些线程可能长时间被阻塞,导致其他线程无法获得足够的CPU时间。 **异步多线程Socket通信** 异步多线程模式结合了异步I/O和多线程的优点。线程不再阻塞...

    界面线程工作线程之间的通讯

    本程序旨在演示如何有效地在这两个线程间传递消息,以实现界面进度条的动态更新以及工作线程的同步通信。 首先,我们要理解多线程的基本概念。在Windows操作系统中,UI更新必须在界面线程中进行,这是因为UI元素由...

    西门子S7-200PLC自由口通讯的两种Delphi实现方法.docx

    在Delphi编程环境中,有两种常见的实现方法,主要涉及到串口通信和多线程技术。 1. **MSComm控件实现** MSComm控件是Microsoft提供的一种ActiveX控件,主要用于串行通信。在Delphi中,可以使用以下步骤来实现: -...

    Java中利用管道实现线程间的通讯

    在Java中,创建线程主要有两种方法: 1. 继承`Thread`类:创建一个新的类,继承自Thread类,然后重写`run()`方法。实例化这个子类的实例就是线程对象,通过调用`start()`方法启动线程,执行`run()`方法。 ```java ...

    彻底明白Java的多线程-线程间的通信.doc

    有两种主要方式:继承`Thread`类和实现`Runnable`接口。 1. **继承Thread类**: 当一个类继承`Thread`,它就成为一个线程类。需要覆盖`run()`方法,并将需要并行执行的任务放入其中。启动线程时,我们调用`start()...

    C_同步异步SOCKET通讯和多线程总结.doc

    Socket通信分为同步和异步两种模式,每种模式都有其适用的场景和特性。 同步Socket通信是阻塞式的,即在发送或接收数据时,程序会暂停执行,等待数据传输完成。这种方式简单易懂,适合数据量较小、实时性要求不高的...

    C#SOCKET 客户端与主机通讯多线程实现

    总结来说,"C# SOCKET 客户端与主机通讯多线程实现"是一个涉及网络编程和多线程技术的项目。通过理解和应用这些知识点,开发者可以构建出能够处理高并发连接的服务器和高效通信的客户端。在实践中,还需要考虑异常...

    c#编写串口通讯代码 多线程实现.rar

    本资料包“c#编写串口通讯代码 多线程实现.rar”显然关注的是如何在C#中使用多线程技术来实现串口通信,从而提高程序的执行效率和响应性。 串口通信的基本概念: 1. **串行通信**:数据逐位按顺序传输,与并行通信...

    TCP/IP多线程通讯

    TCP/IP多线程通讯是计算机网络编程中的一个重要领域,它结合了TCP/IP协议栈与多线程技术,用于实现高效、稳定的数据交换。在本文中,我们将深入探讨这两个关键概念及其在实际应用中的结合。 首先,TCP(传输控制...

    多线程编程之三——线程间通讯

    线程间通信是多线程编程中的核心概念,它允许不同线程之间交换信息和协调工作。当一个程序中存在多个并发...在实际应用中,需要根据任务的性质、数据的复杂性和性能要求来综合考虑,合理设计和实现线程间的通信机制。

    线程间通信方式3:消息传递方式

    消息传递可以作为避免数据竞争的一种手段,因为每个线程通过消息队列顺序地接收和处理消息,而不是直接访问共享数据。 - 但需要注意的是,如果消息涉及到共享资源,仍需使用互斥量或临界区来保护这些资源。 6. **...

    异步和多线程socket通讯

    本文将深入探讨"异步和多线程socket通讯"这一主题,基于提供的描述和标签,我们将讨论如何利用多线程和异步机制来提升socket通信的效率和响应性。 首先,Socket是一种在应用程序与网络服务之间建立连接的接口,它...

    2.线程间同步和通信之信号量(静态)

    信号量有两种类型:二进制信号量(类似于互斥锁)和计数信号量。在本示例中,我们将重点关注静态信号量,即在创建时就分配好内存的信号量。 首先,我们需要了解RT-thread中的信号量API。`rt_sem_init()`函数用于...

    C#多线程通讯[归类].pdf

    这个简单的例子为我们展示了多线程通讯的基础概念,但实际的多线程应用程序可能需要更高级的同步机制和错误处理策略,以确保程序的稳定性和性能。在开发多线程应用时,理解线程的生命周期、同步机制以及死锁和资源...

    两个串口多线程通信

    在IT行业中,多线程通信是...总结起来,实现“两个串口多线程通信”需要对操作系统线程机制、串口通信协议和相关API有深入理解。通过合理设计和有效同步,可以构建稳定、高效的串口通信系统,满足各种应用场景的需求。

    多线程之间通讯5.rar

    2. **管程(Monitor)**:管程是一种在多线程环境中提供同步和互斥访问的机制,通常由Java的synchronized关键字实现。它保证同一时间只有一个线程能进入特定的代码段。 3. **消息传递**:线程通过发送消息进行通信...

Global site tag (gtag.js) - Google Analytics