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

时间: 2024-08-04 13:21:19

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

多口8口16口短信猫池设备与短信猫开发包

多口短信猫池是指集成了8路或16口等多短信通讯模块的短信猫设备,要支持短信猫池二次开发需要相应的短信猫开发包支持,在这里推荐给大家:企业短信平台8.2 支持单口短信猫.8口短信猫和16口短信猫池全系列短信猫设备(GSM短信猫和CDMA短信猫.GPRS短信猫等) 多口8口16口短信猫池设备实物如图: 多口8口16口短信猫池设备所采用的短信猫开发包与普通单口GSM短信猫开发包不所不同,需要相应的短信猫开发包支持多口短信猫池设备才可以,给大家推荐:企业短信平台8.2 此款短信猫开发包基于系统数据库的开

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

16.1 What's the difference between a thread and a process? 进程Process是程序执行时的一个实例.一个进程是被分配系统资源的独立单元,每个进程在独立的地址空间上执行,如果需要使用其他进程的资源,需要使用进程间通讯,包括管道Pipes,文件Files,套接字Sockets,或者其他形式. 线程Thread存在于进程之中并分享进程的资源(包括堆空间).同一个进程中的多个线程分享同一个堆地址.这是和进程区别很大的地方,进程之间不能直接访问内

[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 in one instance of a program, can they both execute A at the same time? Can they execute A and B at the same time? 当我们给一个方法加了synchronized关键字,我们确保了两个线

配送短信猫软件丰富,支持短信猫二次开发

配送短信猫软件丰富,支持短信猫二次开发 短信猫主要是用于二次开发领域,支持将短信收发功能集成.嵌入到其他系统.软件当中.最终实现短信收发除了需要有短信猫硬件外还需要相应短信猫软件的支持,即所谓的短信猫开发包.短信猫SDK或短信猫接口程序.而支持短信猫二次开发的软件非常丰富,有不同款式.有免费有收费,采用不同开发方式. 以下介绍我公司的几款短信猫开发软件,如下: 免费短信猫DLL开发包 提供有多种开发语言示例DEMO,方便程序员开发调用,免费短信猫开发包,免加密狗,自行测试调试使用. 短信服务器8

wavecom工业级短信猫设备有丰富短信猫接口支持

目前市场上的短信猫设备参差不齐采用各种芯片的,大多都是用于短信群%#发广告方面的对于短信猫二次开发支持不理想.而采用wavecom工业级短信猫模块的设备由于其比较成熟的品牌在应用方面比较广泛,兼容性高.稳定性强,相应的短信猫接口软件支持的也比较多.是做短信功能二次开发.系统嵌入式集成应用的首选品牌.工业级短信猫模块主要有wavecom Q2303A/Q2403A/Q2358C几种型号,根据其集成端口数量多少分为单口,8口,16口短信猫完全可满足各类短信应用需求. wavecom工业级短信猫设备及

8口短信猫池开发推荐wavecom原装Q2403A

8口短信猫池多端口短信猫同样支持二次开发,但必须有相应短信猫开发包接口软件的支持,目前市场上大多配送的sms.dll这款免费短信猫开发包是不支持多口短信猫池开发应用的.推荐支持短信猫池二次开发的接口软件:企业短信平台8.2.在短信猫开发应用领域,稳定性永远是第一的.“好马配好鞍”,整个短信系统运行的稳定性除需要强大稳定的接口软件层面的支持外还需要有好的硬件支持,推荐wavecom原装的Q2403A这种短信猫设备. wavecom原装Q2403A模块如图: 原装工业级通讯模块,性能稳定,支持短信.

c# 短信猫池移动空充程序

16口短信猫池2个!  通过发送AT指令实现短信猫充值! 虽然已经实现了功能,但是 我觉得程序有很大的缺陷!   求大神有兴趣的给点设计解决方案

CareerCup All in One 题目汇总

Chapter 1. Arrays and Strings 1.1 Unique Characters of a String 1.2 Reverse String 1.3 Permutation String 1.4 Replace Spaces 1.5 Compress String 1.6 Rotate Image 1.7 Set Matrix Zeroes 1.8 String Rotation Chapter 2. Linked Lists 2.1 Remove Duplicates

多台设备同步 NSUserActivity详解

API介绍 我们看NSUserActivity的官方文档,可以看到下边的这些API: /* NSUserActivity encapsulates the state of a user activity in an application on a particular device, in a way that allows the same activity to be continued on another device in a corresponding application f