java多线程 Semaphore CountDownLatch ScheduledExecutorService
  sAAkk3Vxfaa8 2023年11月02日 63 0


参考:http://www.ibm.com/developerworks/cn/java/j-5things5.html

【关于 java.util.concurrent 您不知道的 5 件事,第 2 部分】

1,Semaphore

适用于:限制未处理的特定资源请求(线程/操作)数量。

public class SemApp {
    public static void main(String[] args) {
        Runnable limitedCall = new Runnable() {
            final Random rand = new Random();
            final Semaphore available = new Semaphore(3);
            int count = 0;
            public void run() {
                int time = rand.nextInt(15);
                int num = count++;
                try {
                    available.acquire();
                    System.out.println("Executing " + 
                        "long-running action for " + 
                        time + " seconds... #" + num);
                    Thread.sleep(time * 1000);
                    System.out.println("Done with #" + 
                        num + "!");
                    available.release();
                } catch (InterruptedException intEx) {
                    intEx.printStackTrace();
                }
            }
        };
        
        for (int i=0; i<10; i++)
            new Thread(limitedCall).start();
    }
}

 程序中实现了,限制了同时打开的任务数是三个。


结果 写道


Executing long-running action for 9 seconds... #0
Executing long-running action for 7 seconds... #2
Executing long-running action for 0 seconds... #1
Done with #1!
Executing long-running action for 1 seconds... #3
Done with #3!
Executing long-running action for 6 seconds... #4
Done with #2!
Executing long-running action for 5 seconds... #5
Done with #4!
Executing long-running action for 6 seconds... #6
Done with #0!
Executing long-running action for 12 seconds... #7
Done with #5!
Executing long-running action for 1 seconds... #8
Done with #8!
Executing long-running action for 12 seconds... #9
Done with #6!
Done with #7!
Done with #9!


 

对于特定资源和线程访问数的限定Semaphore是个不错的选择。这里使用了Semaphore一次使用和释放一个通行证,Semaphore还可以一次使用和释放多个通行证。

2,CountDownLatch

public class CDLApp {
	public static void main(String[] args)
	throws InterruptedException, java.io.IOException {
		System.out.println("Prepping...");
		Race r = new Race(
				"horse 1",	"horse 2",	"horse 3",	"horse 4",
				"horse 5",	"horse 6",	"horse 7",	"horse 8"
		);
		System.out.println("It's a race of " + r.getDistance() + " lengths");
		System.out.println("Press Enter to run the race....");
		System.in.read();
		r.run();
	}
}
class Race {
	private Random rand = new Random();
	private int distance = rand.nextInt(250);
	private List<String> horses = new ArrayList<String>();
	public Race(String... names) {
		this.horses.addAll(Arrays.asList(names));
	}
	public int getDistance() {return distance;}

	public void run() throws InterruptedException {
		System.out.println("And the horses are stepping up to the gate...");
		final CountDownLatch start = new CountDownLatch(1);
		final CountDownLatch finish = new CountDownLatch(horses.size());
		final List<String> places =
			Collections.synchronizedList(new ArrayList<String>());

		for (final String h : horses) {
			new Thread(new Runnable() {
				public void run() {
					try	{
						start.await();//等待赛马开始
						
						System.out.println(h + 
								" stepping up to the gate...");

						int traveled = 0;
						while (traveled < distance)	{
							//前进一次 暂停 0-2 秒
							Thread.sleep(rand.nextInt(3) * 1000);
							//前进 0-14 米
							traveled += rand.nextInt(15);
							System.out.println(h + 
									" advanced to " + traveled + "!");
						}
						System.out.println(h + 
						" crossed the finish!");
						places.add(h);
						
						finish.countDown();//一个马到达终点就 减去一, 倒数完成比赛结束
					}
					catch (InterruptedException intEx) {
						System.out.println("ABORTING RACE!!!");
						intEx.printStackTrace();
					}
				}
			}).start();
		}
		System.out.println("And... they're off!");
		start.countDown();//开始赛马

		finish.await();//等待所有的马跑完
		System.out.println("============================================");
		System.out.println("And we have our winners!");
		System.out.println("<"+places.get(0)+">" + " took the gold...");
		System.out.println("<"+places.get(1)+">" + " got the silver...");
		System.out.println("and " + "<"+places.get(2)+">" + " took home the bronze.");
		System.out.println("============================================");
	}
}

 

上面的程序利用CountDownLatch 描述一个赛马的过程,首先让所有马在门闩那里(start.countDown();//开始赛马)等待开始,每匹马冲过终点后(finish.countDown),finish.await()等待所有的马冲过终点后,发奖牌。

3,ScheduledExecutorService

public class Ping {
	public static void main(String[] args) {
        ScheduledExecutorService ses =
            Executors.newScheduledThreadPool(1);
        Runnable pinger = new Runnable() {
            public void run() {
                System.out.println("PING!");
            }
        };
        ses.scheduleAtFixedRate(pinger, 1, 2, TimeUnit.SECONDS);
    }
}

 

模拟心脏每隔2秒钟跳动一次。顺便说一下,如果用户希望取消心跳,scheduleAtFixedRate 调用将返回一个 ScheduledFuture 实例,它不仅封装了结果(如果有),还拥有一个 cancel 方法来关闭计划的操作。

 

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
sAAkk3Vxfaa8