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. ARM寄存器学习,王明学learn

    ARM寄存器学习 ARM微处理器共有37个32位寄存器,其中31个为通用寄存器,6个为状态寄存器.但是这些寄存器不能被同时访问,具体哪些寄存器是可以访问的,取决ARM处理器的工作状态及具体的运行模式. ...

  2. loj 1030概率dp

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1030 思路:一直以来对这种概率题都挺感冒的=.=......还是说一下思路吧,dp[i ...

  3. 如何在MFC中添加对话栏

  4. LoadRunner IP欺骗(转)

    直接转了篇运用LR来实现IP欺骗的文章. http://www.cnblogs.com/fnng/archive/2013/03/02/2940284.html

  5. 异步框架asyn4j的原理

    启动时调用init方法 public void init(){ if (!run){ run = true; //工作队列 workQueue = newPriorityBlockingQueue(m ...

  6. C#根据html生成PDF

    使用iTextSharp 控件 iTextSharp包括几个dll. 主要iTextSharp版本包含:——itextsharp.dll:核心库——itextsharp.xtra.dll:额外的功能( ...

  7. Angular.js 以及个人学习网站

    Angular.js  教程 http://www.360doc.com/content/14/0414/15/14416931_368816305.shtml web前端学习: 慕课网:http:/ ...

  8. JavaScript设计模式——状态模式

    状态和行为: 所谓对象的状态,通常指的就是对象实例的属性的值:而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上. 状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应 ...

  9. JavaScript 之 document对象

    对象属性document.title //设置文档标题等价于HTML的title标签document.bgColor //设置页面背景色document.fgColor //设置前景色(文本颜色)do ...

  10. [工作bug]一个weblogic跨应用导致session丢失的bug之旅

    近来,发布一个应用,开发和本地测试一切都好,一旦部署到测试环境之后,坑爹的问题随之而来,应用程序不定时的超时,导致用户正在操作过程中被踢了出来,纠结了几天,终于在今天将此问题搞定: 1.系统架构 系统 ...