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. 解释一下SQLSERVER事务日志记录

    解释一下SQLSERVER事务日志记录 大家知道在完整恢复模式下,SQLSERVER会记录每个事务所做的操作,这些记录会存储在事务日志里,有些软件会利用事务日志来读取 操作记录恢复数据,例如:log ...

  2. the last lecture

    2008.07.25,CMU教授Randy Pausch教授因癌症去世,仅47岁. 几年之前,当我看到Pausch先生最后一课的视频时,让我震撼. 转眼之间,7年过去了,这7年,让我成长了许多. 7年 ...

  3. HDU 5919 Sequence II 主席树

    Sequence II Problem Description   Mr. Frog has an integer sequence of length n, which can be denoted ...

  4. windows OBJECT查找

    PspCidTable表里.索引值总之4的倍数.也就是说 PID/4 才是PspCidTable索引.*8 才是PsPCidTable+偏移.获取进程对应的 _HANDLE_TABLE_ENTRY 结 ...

  5. flex容器属性(一)

    一,概念 flexible box ,意为"弹性布局",用来为盒状模型提供最大的灵活性. 块级布局更侧重于垂直方向,行内布局更侧重于水平方向,于此相对的,弹性盒子布局算法是方向无关 ...

  6. 金融左侧js错误

  7. 【转】最近搞Hadoop集群迁移踩的坑杂记

    http://ju.outofmemory.cn/entry/237491 Overview 最近一段时间都在搞集群迁移.最早公司的hadoop数据集群实在阿里云上的,机器不多,大概4台的样子,据说每 ...

  8. [导入]Eclipse 导入/编译 Hadoop 源码

    http://www.cnblogs.com/errorx/p/3779578.html 1.准备工作 jdk: eclipse: Maven: libprotoc :https://develope ...

  9. linux查看和修改系统时间

    设置日期:date -s 20091112 设置时间:date -s 18:30:50 日期和时间一起设置: date 111218302009 (月日时分年) date -s "20091 ...

  10. express随记01

    系统变量的设置 app.get(env) | process.env.NODE_ENV: 会自动判断当前环境类型; app.get(port) | process.env.PORT: 必须手动设置; ...