Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无效_Java_Multithreading_Java Threads_Reentrantlock - Fatal编程技术网

Java 无效

Java 无效,java,multithreading,java-threads,reentrantlock,Java,Multithreading,Java Threads,Reentrantlock,我正在努力理解这种方法。到目前为止,我所了解的是: void lockinterruptbly()-->获取锁(如果可用)并执行正常操作。如果锁不可用,那么线程将进入等待状态,在等待锁对象时,如果线程被中断,它将不会获得锁对象。如果它没有被中断,那么只有它才能得到锁 我试图从Java文档中理解,但我并不十分清楚。 有人能用别的话来表达吗? Possible output 1) Before interrupt Hello.... After t1.interrupt Hello and bef

我正在努力理解这种方法。到目前为止,我所了解的是: void lockinterruptbly()-->获取锁(如果可用)并执行正常操作。如果锁不可用,那么线程将进入等待状态,在等待锁对象时,如果线程被中断,它将不会获得锁对象。如果它没有被中断,那么只有它才能得到锁

我试图从Java文档中理解,但我并不十分清楚。 有人能用别的话来表达吗?

Possible output 1)

Before interrupt Hello....
After t1.interrupt Hello and before t2.start()....
exception caught test1
After t2.start Hello but before t2.interrupt....
After t2.interrupt Hello....
exception caught test2
Main Hello....
Main Hello....
Main Hello....

Possible output 2)

Before interrupt Hello....
After t1.interrupt Hello and before t2.start()....
exception caught test1
After t2.start Hello but before t2.interrupt....
After t2.interrupt Hello....
Main Hello....
Main Hello....
Main Hello....
exception caught test2
此外,我无法理解下面是如何为该程序提供可能的输出的?

Possible output 1)

Before interrupt Hello....
After t1.interrupt Hello and before t2.start()....
exception caught test1
After t2.start Hello but before t2.interrupt....
After t2.interrupt Hello....
exception caught test2
Main Hello....
Main Hello....
Main Hello....

Possible output 2)

Before interrupt Hello....
After t1.interrupt Hello and before t2.start()....
exception caught test1
After t2.start Hello but before t2.interrupt....
After t2.interrupt Hello....
Main Hello....
Main Hello....
Main Hello....
exception caught test2
节目:-

import java.util.concurrent.locks.*;
class Test{
    static Lock1 l = new Lock1(); 
    public void test1() throws InterruptedException{
        l.lockInterruptibly();
        synchronized(l){
        for(int i=0; i<100; i++){
           System.out.println(Thread.currentThread().getName() +" : " + i);
           try{
             Thread.sleep(100);
           }
           catch(InterruptedException e){
            System.out.println(Thread.currentThread().getName() + " got interrupted");     
           }
         }
      }
   }
    public void test2() throws InterruptedException{
        l.lockInterruptibly();
        synchronized(l){
        for(int i=100; i>0; i--){
          System.out.println(Thread.currentThread().getName() +" : " + i);
          try{
             Thread.sleep(100);
          }
          catch(InterruptedException e){
             System.out.println(Thread.currentThread().getName() + " got interrupted");     
          }
        }
      }
    }
 }

class MyThread1 extends Thread{
    Test t;
    MyThread1(String name, Test t){
        super(name);
        this.t = t;
    }
    public void run(){
      try{
      t.test1();
    }
    catch(InterruptedException e){
      System.out.println("exception caught test1");    
    }
  }
}

class MyThread2 extends Thread{
    Test t;
    MyThread2(String name, Test t){
      super(name);
      this.t = t;
    }
    public void run(){
     try{
     t.test2();
    }
    catch(InterruptedException e){
     System.out.println("exception caught test2");    
    }
   }
}
class Lock1 extends ReentrantLock{
}
public class Main{
    public static void main(String[] args) throws InterruptedException {
        Test t = new Test();
        MyThread1 t1 = new MyThread1("thread1",t);
        MyThread2 t2 = new MyThread2("thread2",t);
        t1.start();
        System.out.println("Before interrupt Hello....");
        t1.interrupt();
        System.out.println("After t1.interrupt Hello and before t2.start()....");       
        t2.start();
        System.out.println("After t2.start Hello but before t2.interrupt....");
        t2.interrupt();
        System.out.println("After t2.interrupt Hello....");
        System.out.println("Main Hello....");
        System.out.println("Main Hello....");
        System.out.println("Main Hello....");
    }
}
尽管
main
线程持有对象m的
锁(m.lock())
但它给出了IllegalMonitorStateException,因为它没有对象m的
监视器

希望我的问题更容易理解

我试图从Java docs API中理解,但我不太清楚。有人能用别的话来表达吗

简单的版本是,
l.lockInterruptibly()
l.lock()
做的事情相同,只是在
l.lockInterruptibly()
中等待的线程将立即响应中断,而在
l.lock()
中等待的线程在获得锁之前无法响应


FWIW:有两种不同的方式锁定互斥锁的原因可能是(我猜)您的程序通过调用
lockinterruptablely
而不是调用
lock
来获得性能的影响


但是请注意!还有一个更重要的原因,就是你应该避免
lockInterruptibly
。也就是说,如果您的程序将锁锁定的时间足够长,以至于您关心它是否可中断,那么可能有一种更聪明的方法来协调程序线程的活动。您应该努力使锁的锁定时间不超过分配几个变量所需的时间。

首先要注意的是,当Java中的线程被中断时,所有发生的事情(实际上)就是在该线程上设置一个标志。由线程本身中运行的代码通过调用
thread.interrupted()
来检查此标志。唯一的轻微例外是胎面进入可中断睡眠或等待状态。在这种情况下:

  • 如果已设置中断标志,则立即抛出
    InterruptedException
  • 如果线程在等待过程中被中断,也会抛出一个
    InterruptedException
请注意,当等待或睡眠引发
InterruptedException
时,或者调用
Thread.interrupted()
时,线程的interrupted标志将自动取消设置

考虑到这一点,这里有一个要点来解释您的第一个“可能输出”是如何发生的:

Main                  T1                                T2
|                     .                                 .
--                    .                                 .
Create objects        .                                 .
--                    .                                 .
|                     .                                 .
--                    .                                 .
Start T1 |----------->*                                 .
--                    |                                 .
|                     |                                 .
--                    |                                 .
Print "Before..."     |                                 .
--                    |                                 .
|                     |                                 .
--                    |                                 .
Interrupt T1 |------->|                                 .
--                    --                                .
|                     Enter lockInterruptibly()         .
|                      -Check for interrupt (found)     .
|                      -Throw InterruptedException      .
--                    --
Print "After t1..."   |
--                    --                                .
|                     Print "exception..."              .
|                     --                                .
|                     |                                 .
|                     *                                 .
--                                                      .
Start T2 |--------------------------------------------->*
--                                                      |
|                                                       |
--                                                      |
Print "After t2..."                                     |
--                                                      |
|                                                       |
--                                                      |
Interrupt T2 |----------------------------------------->|
--                                                      --
|                                                       Enter lockInterruptibly()
--                                                       -Check for interrupt (found)
Print "After t2..."                                      -Throw InterruptedException
--                                                      --
|                                                       |
|                                                       --
|                                                       Print "exception..."
--                                                      --
Print "Main Hello...."                                  |
--                                                      *
|
--
Print "Main Hello...."
--
|
--
Print "Main Hello...."
--
|
*
第二次输出几乎相同,除了最后几次打印的顺序

下面是我对
lockinterruptbly()
行为的替代措辞:

  • 首先,如果当前线程上存在未处理的中断,则抛出一个
    InterruptedException
  • 检查锁是否可用
  • 如果没有,则等待它变为可用,或者等待线程被中断
  • 如果线程在锁可用之前中断,则抛出
    InterruptedException
  • 返回(锁现在由调用线程持有)

使用
锁定
是使用
同步
的替代方法。此外,您从未解锁
。如中所示,标准习惯用法是使用
lock.lock();试试{/*保护代码*/}最后{lock.unlcok();}
@raven03,Slaw调用的缺陷是严重的。你应该先解决这些问题,然后看看你是否还有问题。提问比理解答案更容易。尽量放慢速度,吸收别人告诉你的一些内容,而不是不断地发布带有相同错误的问题。发布的代码混合了隐式锁和可重入锁是毫无意义的。我建议你试着吸收你反复得到的关于这个问题的建议。很可能人们发现你的问题不清楚。有时,您似乎关注的是
lockinterruptbly()
如何按合同工作。其他时候,你似乎对
synchronized
Lock
在概念上是如何工作的有一个基本的误解;举个例子,你的例子将两者混合在一起,尽管它们之间除了互斥的概念之外没有任何关系。然后您有一个子类,
Lock1
,它的用途未知,为什么不直接使用
ReentrantLock
?此外,代码的格式也不正确。所有这些都使我们很难确定您实际询问的是什么。因此,为了确保我正确地理解了您,如果在调用l.lockInterruptibly()的线程之前设置了thread Interruptive标志,那么即使当线程调用l.lockInterruptibly()方法并且可以获取锁时,它会抛出InterruptedException,并且不会获得锁?我相信是的,我的意思是这就是你在上面的回答中试图说的,对吗?是的,确实是这样。我恐怕我同意问题下面的许多评论。虽然我很乐意“在字里行间阅读”,并帮助您解决我认为您看到的问题,但如果读者希望了解锁的一般行为,尤其是
lockInterruptibly
,那么所写的问题会让读者感到困惑。正如其他人所提到的,锁和
同步
块的混合尤其令人关注。此外,您粘贴的代码需要一段时间来消化,并且比一个简单的代码要复杂一些。