有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java锁与锁

我看不出有什么区别。我读到:actual-use-of-lockinterruptibly-for-a-reentrantlock

想测试一下。代码如下:

public class Test {
public static void main(String[] args){
    Test test = new Test();
    test.inturreptWork();
    //Main group
    System.out.println("Main Thread group: "+Thread.currentThread().getThreadGroup().getName());
    //System group  is the parent of main group. it contains system level threads like finalizer,signal dispatcher,attach listener
    System.out.println("Main Thread group: "+Thread.currentThread().getThreadGroup().getParent());
}

public void inturreptWork(){
    Inturrept inturrept= new Inturrept();
    Thread t1 = new Thread(inturrept,"Thread 1");
    Thread t2 = new Thread(inturrept,"Thread 2");
    Thread t3 = new Thread(inturrept,"Thread 3");
    try{
    t1.start();
    Thread.sleep(1000);
    t2.start();
    Thread.sleep(1000);
    t2.interrupt();
    t3.start();
    t1.join();
    t2.join();
    t3.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    finally {
        System.out.println("Finally");
    }


}

这是Inturret类

        public class Inturrept implements Runnable {
    Lock lock = new ReentrantLock();

    @Override
    public void run() {
        try {
            System.out.println("Trying to get lock ,Thread name is: " + Thread.currentThread().getName());
            lock.lock();// or   lock.lockInterruptibly();

            System.out.println("Running");
            Thread.sleep(7000);// Use something else to mimic sleep as it throws interrupted exception 
            lock.unlock();// This caused IllegalMonitorStateException 
        } catch (InterruptedException e) {
            System.out.println("I was inturrepted, Thread name is: " + Thread.currentThread().getName());
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

控制台输出:

Trying to get lock ,Thread name is: Thread 1
Running
Trying to get lock ,Thread name is: Thread 2
Trying to get lock ,Thread name is: Thread 3
Running
Exception in thread "Thread 1" I was inturrepted, Thread name is: Thread 2
java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
    at com.test.main.Inturrept.run(Inturrept.java:21)
    at java.lang.Thread.run(Thread.java:748)
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at com.test.main.Inturrept.run(Inturrept.java:15)
    at java.lang.Thread.run(Thread.java:748)
Running
Exception in thread "Thread 3" Finallyjava.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
    at com.test.main.Inturrept.run(Inturrept.java:21)
    at java.lang.Thread.run(Thread.java:748)

Main Thread group: main
Main Thread group: java.lang.ThreadGroup[name=system,maxpri=10]

正如回答中提到的“这与常规锁()相同。但是如果另一个线程中断,等待的线程lockInterruptly()将抛出InterruptedException。” 即使是锁。lock()或lock。锁中断()。线程被中断。那么有什么区别呢?我理解错了吗?请帮忙。 另外一个问题是,为什么我在控制台中看到“线程中的异常”和“线程3”。它运行时,我可以在日志中看到两个“运行”

谢谢你


共 (1) 个答案

  1. # 1 楼答案

    lockInterruptbly()首先检查线程是否中断。如果中断,则抛出InterruptedException

     if (Thread.interrupted())
                throw new InterruptedException();
            if (!tryAcquire(arg))
                doAcquireInterruptibly(arg);
    

    锁。unlock()在代码中调用了两次。所以它抛出IllegalMonitorStateException,因为没有相同的线程执行解锁。当线程在未锁定的情况下执行解锁时,它会抛出异常

     if (Thread.currentThread() != getExclusiveOwnerThread())
                    throw new IllegalMonitorStateException();
    

    线。导致中断异常的睡眠。睡眠方法抛出InterruptedException

    void sleep(long millis) throws InterruptedException
    

    修改代码

     public void run() {
    try {
        System.out.println("Trying to get lock ,Thread name is: " + Thread.currentThread().getName());
        lock.lock();
        System.out.println("Running");
        //Thread.sleep(7000);
    
    } catch (Exception e) {
        System.out.println("I was inturrepted, Thread name is: " + Thread.currentThread().getName());
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
    

    }