[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的.单词的音标.翻译结 ...
随机推荐
- MongoDB学习(2)—Node.js与MongoDB的基本连接示例
前提 已经安装了node.js和MongoDB,本文使用的node.js是v0.12.0,MongoDB是3.0.0. 初始化数据 启动MongoDB服务,在test数据库中插入一条实例数据: db. ...
- -webkit-text-size-adjust
ios使用-webkit-text-size-adjust禁止调整字体大小 body{-webkit-text-size-adjust: 100%!important;} android使用以下代码, ...
- LOAD和PigStorage的一些测试例子 (转)
原地址:http://f.dataguru.cn/thread-233064-1-1.htm 因为理解上的错误,在这里被搞糊涂了.通过做测试,应该算是澄清了,所以写出来. 假设有个文件叫test,该文 ...
- LoadRunner性能测试执行过程的问题
LoadRunner做性能测试 从设计到分析执行 执行测试并分析调优: 测试中报错的信息解决: 1. Failed to connect to server "域名:80": [1 ...
- 利用scp传输文件小结
从本地复制到远程 scp mysql-5.5.29-linux2.6-x86_64.tar.gz 192.168.1.11:/opt 指定端口: scp -P 60022 /opt/ray/nginx ...
- Android Java执行Shell命令
最新内容建议直接访问原文:http://www.trinea.cn/android/android-java-execute-shell-commands/ 主要介绍Android或Java应用中如何 ...
- ZK常用命令
zkcli脚本命令介绍 zkcli 连接默认zookeeper服务器 zkcli -server ip:port 连接指定的zookeeper服务器 create -s -e path d ...
- JavaScrip实现3D旋转动态效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- iOS UITextField的returnkey点击事件
关于隐藏软键盘,网上的办法良莠不齐,大多是通过实现UITextFieldDelegate来隐藏软键盘,该方法代码较多,且在文本框很多的时不好处理.我经过搜索与摸索,找到了最佳的处理办法.(引用的) ...
- Oracle 使用小计(4)
1.oracle字符串分割函数split )定义split_type类型: CREATE OR REPLACE TYPE split_type IS TABLE OF VARCHAR2 (4000) ...