先放上我的代码, 假设有3个函数 first second third 3个线程运行他们我想让3个函数顺寻执行 先执行first 然后second 最后third.
我明白 这个其实是我课本上信号量的习题只要有信号量很简单就能解决
现在我想用lock解决 可以么?
每次判断lock是否lock上 如果lock上 就重新尝试执行本方法一直到其他线程将lock解锁 看似没问题啊
但是我遇到了个错误:
Exception in thread "Thread-0" java.lang.IllegalMonitorStateExceptionpackage CareerCup.ThreadsAndLocks.Q16_5_Foo;import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;public class FooLock extends Thread {    public ReentrantLock lock1, lock2, lock3;    public FooLock() {
        if (lock1 == null) {
            lock1 = new ReentrantLock();
        }
        if (lock2 == null) {
            lock2 = new ReentrantLock();
            lock2.lock();
        }
        if (lock3 == null) {
            lock3 = new ReentrantLock();
            lock3.lock();
        }
    }    public boolean first() throws InterruptedException {
        if (lock1.isLocked()) {
            Thread.sleep(10000);
            first();
        }
        System.out.println("first");
        lock2.unlock();
        return false;
    }    public boolean second() throws InterruptedException {
        if (lock2.isLocked()) {
            Thread.sleep(10000);
            second();        }
        System.out.println("second");
        lock3.unlock();
        return false;
    }    public boolean third() throws InterruptedException {
        if (lock3.isLocked()) {
            Thread.sleep(10000);
            third();
        }
        System.out.println("third");
        return false;
    }    public static void main(String[] args) throws InterruptedException {
    }
}
package CareerCup.ThreadsAndLocks.Q16_5_Foo;import java.util.logging.Level;
import java.util.logging.Logger;public class FooLockThread extends Thread {    int i;
    FooLock fl;    public FooLockThread(int i) {
        this.i = i;
        fl = new FooLock();
    }    @Override
    public void run() {
        try {
            switch (i) {
                case 1:                    fl.first();                    break;
                case 2:
                    fl.second();
                    break;
                case 3:
                    fl.third();
                    break;
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(FooLockThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            FooLockThread flt = new FooLockThread(i + 1);
            flt.start();
        }
    }
}

解决方案 »

  1.   

     * <pre>
     * class X {
     *   private final ReentrantLock lock = new ReentrantLock();
     *   // ...
     *
     *   public void m() {
     *     lock.lock();  // block until condition holds
     *     try {
     *       // ... method body
     *     } finally {
     *       lock.unlock()
     *     }
     *   }
     * }
     * </pre>
    翻了下源码,发现用法原来是这样的。
      

  2.   

    可以用一个线程去唤醒另外一个线程起来继续执行。
    package com.study.test;public class T {

    public static void main(String[] args) throws Exception {
    ThreadTest t4 = new ThreadTest();
    ThreadTest t3 = new ThreadTest(t4);
    ThreadTest t2 = new ThreadTest(t3);
    ThreadTest t1 = new ThreadTest(t2);
    t1.setName("t1");
    t2.setName("t2");
    t3.setName("t3");
    t4.setName("t4");

    t4.start();
    t3.start();
    t2.start();
    t1.start();

    try {
    Thread.sleep(3000);
    System.out.println("主线程醒过来");
    } catch (Exception e) {
    e.printStackTrace();
    }
    t1.interrupt();
    System.out.println("中断t1的睡眠");
    }
    }class ThreadTest extends Thread{
    private Thread controled;
    private boolean goon;
    public ThreadTest(Thread thread){
    controled = thread;
    }
    public ThreadTest(){
    }
    public void run(){
    while(!goon){
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    this.goon = true;
    System.out.println(getName() + "的睡眠被中断");
    }
    }
    System.out.println(getName());
    if(controled != null){
    controled.interrupt();
    System.out.println("中断" + controled.getName() + "的睡眠");
    }
    }
    public void goOn(boolean flag){
    goon = flag;
    }
    }