从两个不同的线程同时调用2个方法 - Java

时间:2013-02-18 09:21:52

标签: java multithreading synchronization

如果同时从两个不同的线程调用这些方法,结果会是什么?

public class FirstWord {
       public static synchronized void writeFirstWord(boolean fromSecondWord) throws Exception {
              if(fromSecondWord == false)
                     SecondWord.writeSecondWord();
              System.out.print("Redflex"); }}

public class SecondWord {
       public static synchronized void writeSecondWord() throws Exception {
              Thread.sleep(100);
              FirstWord.writeFirstWord(true);  
              System.out.print(" Traffic Systems"); }}

4 个答案:

答案 0 :(得分:1)

在您拥有的代码示例中很可能出现死锁 - 如果您有2个线程,比如说ThreadA和ThreadB,那么就给出了这个场景:

ThreadA调用FirstWord.writeFirstWord(false)并且线程在内部暂停 ThreadB调用SecondWord.writeSecondWord()并且线程在

内暂停一次

现在ThreadA继续它将在SecondWord.writeSecondWord();停止,因为ThreadB具有锁定SecondWord。

ThreadB无法继续,因为ThreadA锁定了FirstWord。

结果是僵局。

请注意,这不是此代码的唯一可能结果 - 取决于时间等,代码可能运行一段时间,但很可能你会遇到死锁某点。

答案 1 :(得分:0)

由于sleep()的不可预测性,结果无法预测。

此外,它取决于您有多少核心,以及您在writeFirstWord(boolean)电话中提供的参数。

我会留给你弄清楚细节: - )


提示:一种可能性就是死锁。

答案 2 :(得分:0)

示例SSCCE(已修改):

public class ThreadTest {

    public static void main(String[] args) {
        new Thread() {
            public void run() {
                try {
                    FirstWord.writeFirstWord(false);
                } catch (Exception e) {
                    e.printStackTrace();
                }  
            }
        }.start();

        new Thread() {
            public void run() {
                try {
                    SecondWord.writeSecondWord(false);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

}

class FirstWord {
    public static synchronized void writeFirstWord(boolean fromSecondWord) throws Exception {
        System.out.println("FirstWord start");
        Thread.sleep(100);
        if (!fromSecondWord) SecondWord.writeSecondWord(true);
        System.out.println("FirstWord end");
    }
}

class SecondWord {
    public static synchronized void writeSecondWord(boolean fromFirstWord) throws Exception {
        System.out.println("SecondWord start");
        Thread.sleep(100);
        if (!fromFirstWord) FirstWord.writeFirstWord(true);  
        System.out.println("SecondWord end");
    }
}

如您所见,控制台显示:

FirstWord start
SecondWord start

第一个线程“进入”FirstWord同步块,而第二个线程进入SecondWord块。然后,在稍微休眠之后,第一个线程尝试进入SecondWord方法,并且必须等待,因为第二个线程具有该方法的锁定。

当发生这种情况时,第二个线程也在等待获得另一个锁,这就是两个线程阻塞并且永远不会到达“end”的原因,因为它们永远不会获得两个锁< /强>

如果您在两种方法中删除Thread.sleep,它可能会有效。如上所述,这是不可预测的。您无法先知道要进入哪个线程。

答案 3 :(得分:0)

package com.blt;

    public class ThreadsExample implements Runnable { 
       public static void main(String args[]) {     
        Thread t=new Thread(new ThreadsExample());
        Thread t1=new Thread(new ThreadsExample());     
        t.start();
        t1.start();      
}

    public void run()  {    
    try { 
        writeSecondWord();  
    }   
    catch(Exception e)  {   
      e.printStackTrace();  
    }
 }

    public static synchronized void writeSecondWord() throws Exception {
        Thread.sleep(100);
        writeFirstWord(true);  
        System.out.print(" Traffic Systems"); 
        } 

    public static synchronized void writeFirstWord(boolean fromSecondWord) throws Exception {
        if(fromSecondWord == false)
               writeSecondWord();
        System.out.print("Redflex"); 
     }
 }

输出为:Redflex Traffic SystemsRedflex Traffic Systems

运行在代码之上是正常的,但是代码在某些时候会产生死锁的可能性很大。