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 All in One 题目汇总

[CareerCup] 16.5 Semphore 信号旗的更多相关文章

  1. [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 ...

  2. [CareerCup] 16.4 A Lock Without Deadlocks 无死锁的锁

    16.4 Design a class which provides a lock only if there are no possible deadlocks. 有很多方法可以避免死锁的发生,一个 ...

  3. [CareerCup] 16.3 Dining Philosophers 哲学家聚餐问题

    16.3 In the famous dining philosophers problem, a bunch of philosophers are sitting around a circula ...

  4. [CareerCup] 16.2 Measure Time in a Context Switch 测量上下文转换的时间

    16.2 How would you measure the time spent in a context switch? 上下文转换发生在两个进程之间,比如让一个等待进程进入执行和让一个运行进程进 ...

  5. [CareerCup] 16.1 Thread and Process 线程和进程

    16.1 What's the difference between a thread and a process? 进程Process是程序执行时的一个实例.一个进程是被分配系统资源的独立单元,每个 ...

  6. CareerCup All in One 题目汇总

    Chapter 1. Arrays and Strings 1.1 Unique Characters of a String 1.2 Reverse String 1.3 Permutation S ...

  7. 在Linux下用C语言实现短信收发

     本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lyserver/archive/2008/10/01/3007090.aspx 首先,我根据功能需要创建了几个头文件 ...

  8. iOS 8 Handoff 开发指南

    (原文:Working with Handoff in iOS 8 作者:Gabriel Theodoropoulos 译者:半圆圆) 我想用下面这一个美妙的场景来开始这篇教程:假象一下你正在Mac上 ...

  9. Java程序员必备英文单词

    列表中共有769个单词,这些单词是从JDK.Spring.SpringBoot.Mybatis的源码中解析得到,按照在源码中出现的频次依次排列,页面中的单词是出现频次大于1000的.单词的音标.翻译结 ...

随机推荐

  1. jackson对多态or多子类序列化的处理配置

    [TOC] Jackson Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json.xml转换成Java对象. 多态类型的处理 jackson允许配置多态类型处理, ...

  2. pythonchallenge之C++学习篇-02

    第二关任然是一个字符处理的关卡 查看网页源码发现有一大串字符需要处理,这么多的字符如果放在源代码里就很不好了 所以要用到C++对文件的操作,用到的头文件是fstream 这里参照了这个博文 对文件处理 ...

  3. C语言连接SQLSERVER数据库

    第一步:配置ODBC.在配置ODBC时有用户DSN.系统DSN.和文件DSN三种方法,为了稳妥起见,采用系统DSN. DSN的名字叫LocalServer,帐号:sa,密码123456 第二步:打开V ...

  4. hdu4968

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=4968 说是考dp,但是我没出来dp在哪,可能贪心思想更多一些吧. AC代码: #inclu ...

  5. DSP using MATLAB 示例Example3.21

    代码: % Discrete-time Signal x1(n) % Ts = 0.0002; n = -25:1:25; nTs = n*Ts; Fs = 1/Ts; x = exp(-1000*a ...

  6. 得到UIView中某个非子视图在UIView中的位置

    使用 convertRect: fromView: 或者 convertRect: toView:例如一个视图控制器的view中有一个UITableView,UITableView的某个cell中有个 ...

  7. STL UVA 11991 Easy Problem from Rujia Liu?

    题目传送门 题意:训练指南P187 分析:用vector存id下标,可以用map,也可以离散化用数组存(发现不用离散化也可以) map #include <bits/stdc++.h> u ...

  8. CF# Educational Codeforces Round 3 B. The Best Gift

    B. The Best Gift time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  9. 2014-2015 ACM-ICPC, NEERC, Moscow Subregional Contest E. Equal Digits

    E. Equal Digits time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  10. ccc 播放动画

    cc.Class({ extends: cc.Component, properties: { anim:cc.Animation, }, // use this for initialization ...