[CareerCup] 16.5 Semphore 信号旗
16.5 Suppose we have the following code:
public class Foo {
public Foo() { . . . }
public void first() { ... }
public void second() { ... }
public void thirdQ { ... }
}
The same instance of Foo will be passed to three different threads. ThreadA will call first, threads will call second, and threadC will call third. Design a mechanism to ensure that first is called before second and second is called before third.
按照题目中要求的顺序即需满足在执行second()前检测first()是否完成了,在执行third()前检测second()是否完成了,由于我们需要考虑线程安全,所以布尔型的标记不行,那么使用锁呢,看如下代码:
import java.util.concurrent.locks.ReentrantLock;
public class FooBad {
public int pauseTime = 10000;
public ReentrantLock lock1;
public ReentrantLock lock2;
public FooBad() {
try {
lock1 = new ReentrantLock();
lock2 = new ReentrantLock();
lock1.lock();
lock2.lock();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void first() {
try {
System.out.println("Started Executing 1");
Thread.sleep(pauseTime);
System.out.println("Finished Executing 1");
lock1.unlock();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void second () {
try {
lock1.lock();
lock1.unlock();
System.out.println("Started Executing 2");
Thread.sleep(pauseTime);
System.out.println("Finished Executing 2");
lock2.unlock();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void third() {
try {
lock2.lock();
lock2.unlock();
System.out.println("Started Executing 3");
Thread.sleep(pauseTime);
System.out.println("Finished Executing 3");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public class MyThread extends Thread {
private String method;
private FooBad foo;
public MyThread(FooBad foo, String method) {
this.method = method;
this.foo = foo;
}
public void run() {
if (method == "first") {
foo.first();
} else if (method == "second") {
foo.second();
} else if (method == "third") {
foo.third();
}
}
}
public class j {
public static void main(String[] args) {
FooBad foo = new FooBad();
MyThread thread1 = new MyThread(foo, "first");
MyThread thread2 = new MyThread(foo, "second");
MyThread thread3 = new MyThread(foo, "third");
thread3.start();
thread2.start();
thread1.start();
}
}
上述代码并不能很好的完成题目中要求的顺序,因为锁的所有权的问题。一个线程操作一个锁,当别的线程是无法解这个线程的锁的,所以用锁是不行的。我们可以使用信号旗Semaphores,参见代码如下:
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Foo {
public int pauseTime = 1000;
public Semaphore sem1;
public Semaphore sem2; public Foo() {
try {
sem1 = new Semaphore(1);
sem2 = new Semaphore(1);
sem1.acquire();
sem2.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
} public void first() {
try {
System.out.println("Started Executing 1");
Thread.sleep(pauseTime);
System.out.println("Finished Executing");
sem1.release();
} catch (Exception ex) {
ex.printStackTrace();
}
} public void second() {
try {
sem1.acquire();
sem1.release();
System.out.println("Started Executing 2");
Thread.sleep(pauseTime);
System.out.println("Finished Executing 2");
sem2.release();
} catch (Exception ex) {
ex.printStackTrace();
}
} public void third() {
try {
sem2.acquire();
sem2.release();
System.out.println("Started Executing 3");
Thread.sleep(pauseTime);
System.out.println("Finished Executing 3");
} catch (Exception ex) {
ex.printStackTrace();
}
}
} public class MyThread extends Thread {
private String method;
private Foo foo; public MyThread(Foo foo, String method) {
this.method = method;
this.foo = foo;
} public void run() {
if (method == "first") {
foo.first();
} else if (method == "second") {
foo.second();
} else if (method == "third") {
foo.third();
}
}
} public class j {
public static void main(String[] args) {
Foo foo = new Foo(); MyThread thread1 = new MyThread(foo, "first");
MyThread thread2 = new MyThread(foo, "second");
MyThread thread3 = new MyThread(foo, "third"); thread3.start();
thread2.start();
thread1.start();
}
}
[CareerCup] 16.5 Semphore 信号旗的更多相关文章
- [CareerCup] 16.6 Synchronized Method 同步方法
16.6 You are given a class with synchronized method A and a normal method B. If you have two threads ...
- [CareerCup] 16.4 A Lock Without Deadlocks 无死锁的锁
16.4 Design a class which provides a lock only if there are no possible deadlocks. 有很多方法可以避免死锁的发生,一个 ...
- [CareerCup] 16.3 Dining Philosophers 哲学家聚餐问题
16.3 In the famous dining philosophers problem, a bunch of philosophers are sitting around a circula ...
- [CareerCup] 16.2 Measure Time in a Context Switch 测量上下文转换的时间
16.2 How would you measure the time spent in a context switch? 上下文转换发生在两个进程之间,比如让一个等待进程进入执行和让一个运行进程进 ...
- [CareerCup] 16.1 Thread and Process 线程和进程
16.1 What's the difference between a thread and a process? 进程Process是程序执行时的一个实例.一个进程是被分配系统资源的独立单元,每个 ...
- CareerCup All in One 题目汇总
Chapter 1. Arrays and Strings 1.1 Unique Characters of a String 1.2 Reverse String 1.3 Permutation S ...
- 在Linux下用C语言实现短信收发
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lyserver/archive/2008/10/01/3007090.aspx 首先,我根据功能需要创建了几个头文件 ...
- iOS 8 Handoff 开发指南
(原文:Working with Handoff in iOS 8 作者:Gabriel Theodoropoulos 译者:半圆圆) 我想用下面这一个美妙的场景来开始这篇教程:假象一下你正在Mac上 ...
- Java程序员必备英文单词
列表中共有769个单词,这些单词是从JDK.Spring.SpringBoot.Mybatis的源码中解析得到,按照在源码中出现的频次依次排列,页面中的单词是出现频次大于1000的.单词的音标.翻译结 ...
随机推荐
- ARM寄存器学习,王明学learn
ARM寄存器学习 ARM微处理器共有37个32位寄存器,其中31个为通用寄存器,6个为状态寄存器.但是这些寄存器不能被同时访问,具体哪些寄存器是可以访问的,取决ARM处理器的工作状态及具体的运行模式. ...
- loj 1030概率dp
题目链接:http://lightoj.com/volume_showproblem.php?problem=1030 思路:一直以来对这种概率题都挺感冒的=.=......还是说一下思路吧,dp[i ...
- 如何在MFC中添加对话栏
- LoadRunner IP欺骗(转)
直接转了篇运用LR来实现IP欺骗的文章. http://www.cnblogs.com/fnng/archive/2013/03/02/2940284.html
- 异步框架asyn4j的原理
启动时调用init方法 public void init(){ if (!run){ run = true; //工作队列 workQueue = newPriorityBlockingQueue(m ...
- C#根据html生成PDF
使用iTextSharp 控件 iTextSharp包括几个dll. 主要iTextSharp版本包含:——itextsharp.dll:核心库——itextsharp.xtra.dll:额外的功能( ...
- Angular.js 以及个人学习网站
Angular.js 教程 http://www.360doc.com/content/14/0414/15/14416931_368816305.shtml web前端学习: 慕课网:http:/ ...
- JavaScript设计模式——状态模式
状态和行为: 所谓对象的状态,通常指的就是对象实例的属性的值:而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上. 状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应 ...
- JavaScript 之 document对象
对象属性document.title //设置文档标题等价于HTML的title标签document.bgColor //设置页面背景色document.fgColor //设置前景色(文本颜色)do ...
- [工作bug]一个weblogic跨应用导致session丢失的bug之旅
近来,发布一个应用,开发和本地测试一切都好,一旦部署到测试环境之后,坑爹的问题随之而来,应用程序不定时的超时,导致用户正在操作过程中被踢了出来,纠结了几天,终于在今天将此问题搞定: 1.系统架构 系统 ...