[原创]AutoResetEvent, ManualResetEvent的Java模拟

 

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.");
    }

}
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值