2016-11-26 118 views
1

我有一个方法线程同步执行操作顺序

public static synchronized void print(String message, int sleepTime) throws InterruptedException { 
    System.out.println(message); 
    Thread.sleep(sleepTime); 
} 

调用此方法打印任何消息,我给它,并导致调用它来暂停指定的时刻线程。该static synchronized使得它使这一类的多线程必须同步他们的print以便完成另一个线程之前睡觉(除了第一个线程调用,当然print)没有线程可以开始打印

别的地方在我的代码,我有调用线程这样做:

print("some message", 1000); 
print("some other message", 1000); 

每个审判我已经使用这个代码运行导致打印的第一条消息“一些信息”第一,其次是印刷“一些其他信息”最后所有线程的所有线程。

举例来说,如果我有3个线程,预期结果如下(我可以让他们当我运行了几次代码):

some message 
some message 
some message 
some other message 
some other message 
some other message 

诚然,我还没有运行许多试验。但是,我怀疑一个完成打印第一条消息(让我们调用这个线程A)的线程将与可能还没有打印第一条消息的其他线程(让我们称之为这样的线程B)竞争。 是否有可能的是,调度程序挑选的拾取乙用于第一时间,从而使所述第二消息之前的第二时间在某处被所述第一消息的所有实例都完成打印之前打印?

换句话说,是有可能,这可能发生:

some message 
some message 
some other message 
some message 
some other message 
some other message 

如果上面的序列是可能的,我怎么能保证它不发生?我如何保证第一个序列是总是发生的序列?

+0

你说的第一顺序是什么意思?你最后两个问题都是矛盾的吗? – developer

+0

第一序列,我的意思是打印所有“一些消息”行之前打印所有“一些其他消息”行。第二个序列是具有交换消息的序列。我指的是每个代码块的一个序列。 – Manuel

+0

好的,但你为什么要这么做?目标不是很清楚。 – developer

回答

2

这取决于你的意思是可能的。绝对没有禁止它的规则。但是,您正在使用的实现中所做的特定设计选择可能会导致实际上无法实现。

1

是否有可能的是,调度程序挑选的拾取 乙用于第一时间,从而使所述第二消息之前的第二时间要打印 某处所述第一消息的所有实例都完成 打印前?

是的,这是可能的,线程调度器可以再次选择相同的线程。

此外,还有一个参数,你可能会感兴趣,你需要仔细检查的是两个线程的优先级相同的或不,这可能会导致线程匮乏的解释here,这导致同一线程运行一次又一次。只需添加,您可以通过调用setPriority(int newPriority)将优先级设置为Thread,如API here中所示。

+0

该链接不适合我,但我想我知道你在做什么。基本上,如果在调度程序选择的任何队列中始终存在具有较高优先级线程的流,那么优先级较低的线程将永远不会运行,对吧? – Manuel

+0

我已经更新了链接,它现在可用 – developer

1

这绝对是可能的。我运行了一个简单的多线程程序,它有3个线程,我确实得到了你想要的互锁消息。

public class ThreadSyncTest { 

    public static void main(String[] args) { 

     ThreadSyncTest t = new ThreadSyncTest(); 
     TempThread r1 = t.new TempThread(); 
     Thread t1 = new Thread(r1); 

     TempThread r2 = t.new TempThread(); 
     Thread t2 = new Thread(r2); 

     TempThread r3 = t.new TempThread(); 
     Thread t3 = new Thread(r3); 

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

    } 

    public static synchronized void print(String message, int sleepTime) throws InterruptedException { 
     System.out.println(message); 
     Thread.sleep(sleepTime); 

    } 

    class TempThread implements Runnable{ 

     @Override 
     public void run() { 
      while(true){ 
       try { 
        print("some message", 1000); 
        print("some other message", 1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 

    } 


} 

结果:

some message 
some message 
some other message 
some message 
some other message 
some message 
some message 
some other message 
some message 
some other message