- 浏览: 28176 次
- 性别:
- 来自: 杭州
-
最新评论
AutoResetEvent, ManualResetEvent是C#中常用的线程同步方法,在Java中可以模拟,AutoResetEvent使用Semaphore,增加的是许可证数量,程序里只有一个许可证,那么当这个许可被使用后,就会自动锁定。相反,ManualResetEvent使用countdownlatch,增加的是“latch”,也就是障碍,或者门闩;当障碍解除时,所有程序都可以运行而不被阻塞,如果要实现同步,就必须manual reset,也就是手动加latch。
import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; public class AutoResetEvent { private final Semaphore event; private final Integer mutex; public AutoResetEvent(boolean signalled) { event = new Semaphore(signalled ? 1 : 0); mutex = new Integer(-1); } public void set() { synchronized (mutex) { if (event.availablePermits() == 0) { event.release(); } } } public void reset() { event.drainPermits(); } public void waitOne() throws InterruptedException { event.acquire(); } public boolean waitOne(int timeout, TimeUnit unit) throws InterruptedException { return event.tryAcquire(timeout, unit); } public boolean isSignalled() { return event.availablePermits() > 0; } public boolean waitOne(int timeout) throws InterruptedException { return waitOne(timeout, TimeUnit.MILLISECONDS); } }
AutoResetEvent在MSDN中的例子程序在http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx
我们可以改写一个java版本,用的是java版本的AutoResetEvent
import java.util.Date; import java.util.Random; class TermInfo { public long[] terms; public int order; public long baseValue; public AutoResetEvent trigger; } public class AutoResetEventTest { private final static int numTerms = 3; public static void main(String[] args0) throws InterruptedException { AutoResetEvent trigger = new AutoResetEvent(false); TermInfo tinfo = new TermInfo(); Thread termThread; long[] terms = new long[numTerms]; int result = 0; tinfo.terms = terms; tinfo.trigger = trigger; for (int i = 0; i < numTerms; i++) { tinfo.order = i; // Create and start the term calc thread. TermThreadProc termThreadProc = new TermThreadProc(tinfo); termThread = new Thread(termThreadProc); termThread.start(); // simulate a number crunching delay Thread.sleep(1000); Date date = new Date(); tinfo.baseValue = Integer.parseInt(String.valueOf((date.getTime())).substring(10)); trigger.set(); termThread.join(); result += terms[i]; } System.out.format("Result = %d", result); System.out.println(); } } class TermThreadProc implements Runnable { public TermInfo termInfo; public TermThreadProc(TermInfo termInfo) { this.termInfo = termInfo; } @Override public void run() { TermInfo tinfo = termInfo; System.out.format("Term[%d] is starting...", tinfo.order); System.out.println(); // set the precalculation Date date = new Date(); long preValue = Integer.parseInt(String.valueOf((date.getTime())).substring(10)) + tinfo.order; // wait for base value to be ready try { tinfo.trigger.waitOne(); } catch (InterruptedException e) { e.printStackTrace(); } Random rnd = new Random(tinfo.baseValue); tinfo.terms[tinfo.order] = preValue * rnd.nextInt(10000); System.out.format("Term[%d] has finished with a value of: %d", tinfo.order, tinfo.terms[tinfo.order]); System.out.println(); } }
//ManualResetEvent 的Java实现
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class ManualResetEvent
{
private volatile CountDownLatch event;
private final Integer mutex;
public ManualResetEvent(boolean signalled)
{
mutex = new Integer(-1);
if (signalled)
{
event = new CountDownLatch(0);
}
else
{
event = new CountDownLatch(1);
}
}
public void set()
{
event.countDown();
}
public void reset()
{
synchronized (mutex)
{
if (event.getCount() == 0)
{
event = new CountDownLatch(1);
}
}
}
public void waitOne() throws InterruptedException
{
event.await();
}
public boolean waitOne(int timeout, TimeUnit unit) throws InterruptedException
{
return event.await(timeout, unit);
}
public boolean isSignalled()
{
return event.getCount() == 0;
}
public boolean waitOne(int timeout) throws InterruptedException
{
return waitOne(timeout, TimeUnit.MILLISECONDS);
}
}
MSDN地址:http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx
Java测试:
import java.util.Scanner; import java.io.IOException; public class ManualResetEventTest { // mre is used to block and release threads manually. It is // created in the unsignaled state. static AutoResetEvent mre = new AutoResetEvent(false); public static void main(String[] arg0) throws IOException, InterruptedException { System.out.println("\nStart 3 named threads that block on a ManualResetEvent:\n"); Scanner keyIn = new Scanner(System.in); System.out.print("Press the enter key to continue"); keyIn.nextLine(); for (int i = 0; i <= 2; i++) { threadProc threadProc = new threadProc(); Thread t = new Thread(threadProc); t.setName("Thread_" + i); t.start(); } Thread.sleep(500); System.out.println("\nWhen all three threads have started, press Enter to call Set()" + "\nto release all the threads.\n"); keyIn.nextLine(); mre.set(); Thread.sleep(500); System.out.println("\nWhen a ManualResetEvent is signaled, threads that call WaitOne()" + "\ndo not block. Press Enter to show this.\n"); keyIn.nextLine(); for (int i = 3; i <= 4; i++) { threadProc threadProc = new threadProc(); Thread t = new Thread(threadProc); t.setName("Thread_" + i); t.start(); } Thread.sleep(500); System.out.println("\nPress Enter to call Reset(), so that threads once again block" + "\nwhen they call WaitOne().\n"); keyIn.nextLine(); mre.reset(); // Start a thread that waits on the ManualResetEvent. threadProc threadProc = new threadProc(); Thread t5 = new Thread(threadProc); t5.setName("Thread_5"); t5.start(); Thread.sleep(500); System.out.println("\nPress Enter to call Set() and conclude the demo."); keyIn.nextLine(); mre.set(); } } class threadProc implements Runnable { @Override public void run() { String name = Thread.currentThread().getName(); System.out.println(name + " starts and calls mre.WaitOne()"); try { ManualResetEventTest.mre.waitOne(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + " ends."); } }
发表评论
-
深入了解字符集和编码
2012-03-09 17:21 933一、什么是字符集?什么是编码? 字符(Characte ... -
精确解释Unicode
2012-03-09 14:34 890转自 http://blog.csdn.net/gqqnb/a ... -
[转]字符编码详解及由来(UNICODE,UTF-8,GBK)
2012-03-08 17:55 733from http://blog.csdn.net/st ... -
velocity 笔记
2012-02-24 13:54 931Single quotes will ensure that ... -
[转]java InputStream读取数据问题
2012-01-30 11:25 926http://www.cnblogs.com/MyFa ... -
windows 文件名 正则表达式
2011-09-30 17:14 2272一个简单的windows 文件名 正则表达式,不检查文件名如 ... -
[转]HD9001: 各浏览器对 URI 中非 ASCII 字符的处理有差异
2011-08-25 15:56 1095作者:孙东国 标准参考 URI 的组成如下所示: ... -
【原创】各种编码的关系
2011-07-02 15:54 1027以下为个人总结,有问题欢迎指出。 ASCII 8位 I ... -
【转】Facebook 的系统架构
2011-06-13 14:27 966来源:http://www.quora.co ... -
[转]java并发编程实践笔记
2011-04-07 17:27 7871, 保证线程安全的三种方法 :a, 不要跨线程访问共享变 ... -
[转]java 线程小结
2011-04-07 16:23 10211, 为什么wait与notify之前必须要加synchr ... -
[转]Java集合的五点体会
2011-04-06 10:17 688The Collections classes in j ...
相关推荐
在多线程编程中,`AutoResetEvent` 和 `ManualResetEvent` 是两种重要的同步原语,用于控制线程间的协作和同步。本压缩包文件提供了关于这两种事件类型的实例代码,帮助开发者理解它们的工作原理和用法。 首先,让...
引入命名空间: using System.Threading; AutoResetEvent: autoResetEvent.WaitOne();//运行完后,**自动将事件...ManualResetEvent: manulResetEvent.WaitOne();//运行完后,**不会自动将事件状态设置为无信号**
与AutoResetEvent的区别在于,ManualResetEvent在释放一次后不会自动重置,需要开发者手动调用Reset方法来恢复到未设置状态。 **初始化ManualResetEvent** ManualResetEvent的构造函数允许我们初始化其初始状态。...
与`AutoResetEvent`不同,`ManualResetEvent`在释放一次后不会自动重置,需要手动调用`Reset()`方法来恢复未启动状态。 **一、构造函数** `ManualResetEvent`有两个构造函数: 1. `ManualResetEvent(false)`:初始...
// 模拟耗时操作 Thread.Sleep(new Random().Next(1000, 3000)); Console.WriteLine($"线程 {threadIndex} 执行完成..."); Interlocked.Increment(ref finishedThreads); // 增加完成线程计数 if ...
3. **手动重置**:与`ManualResetEvent`不同,`AutoResetEvent`只允许一个线程通过,如果需要多次触发,需要再次调用`Set()`方法。 ### 四、AutoResetEvent的使用 在C#中,我们可以这样使用`AutoResetEvent`: ``...
搞过C#多线程的人对其中的AutoResetEvent和ManualResetEvent这两个类都理解,其中的WaitOne()方法和Set()以及Reset()方法在线程同步当中用的是比较多的。 AutoResetEvent :当某个线程执行到WaitOne()方法时,该线程...
Mutex(互斥锁)和AutoResetEvent(自动重置事件)是.NET框架提供的两种工具,用于解决这些问题。 Mutex是一种全局资源锁,它允许在任何时间只有一个线程访问特定的资源或代码段。在C#中,我们可以使用Mutex的构造...
AutoResetEvent 允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。 线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前...
`AutoResetEvent`是.NET框架提供的一种线程同步机制,用于控制线程间的通信和协调。在本示例中,我们看到“autoResetEvent示例”描述了一个场景:一个线程负责添加任务,而另外三个线程则负责取出任务并进行计算。...
多线程使用AutoResetEvent
本文将重点解析多线程中的线程同步机制,特别是`AutoResetEvent`和`ManualResetEvent`这两种关键同步对象的特性和使用场景。 #### 终止状态与非终止状态:理解线程的生命周期 在多线程编程中,线程的生命周期至关...
就知道AutoResetEvent这个东西和线程有关,用于处理线程切换之类,于是决定用AutoResetEvent来处理上面的问题。 于是网上查找相关资料: 原来,AutoResetEvent在.Net多线程编程中经常用到。当某个线程调用WaitOne...
最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也简要提了一下System.Threading....
在.NET框架中,`ManualResetEvent`和`AutoResetEvent`是两个常用的线程同步工具,它们基于内核对象——事件对象。事件对象可以处于“信号”或“无信号”状态,当线程等待一个无信号的事件时,它会被挂起,直到其他...
在这个名为“多线程实验_1”的项目中,我们主要探讨了四种关键的多线程操作:AutoResetEvent、ManualResetEvent、Thread.Join()以及委托多线程回调。下面将对这些知识点进行详细的解释和探讨。 首先,`...
AutoResetEvent和ManualResetEvent是事件对象,用于线程间的通信和同步,其中AutoResetEvent在释放一个等待线程后自动重置,而ManualResetEvent则需要手动重置。 在设计多线程程序时,应当避免使用Thread.Abort来...
// 模拟耗时操作 for (int i = 0; i ; i++) { } Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId} exits the critical section."); mutex.ReleaseMutex(); // 使用AutoResetEvent进行控制...
5. **事件(Event)**:`AutoResetEvent`和`ManualResetEvent`可以作为线程间通信的信号,当生产者生产完一个产品或者消费者消费完一个产品后,可以通过设置事件来通知对方。 在C#窗体应用中,可能通过按钮控制生产...