2015-05-19 63 views
1

我想知道如何使这些线程一个接一个地工作,以及如何使第一个线程在第二个线程之后始终运行。我创建了一个信号量,但我不确定如何使用它。使用信号灯

public class A extends Thread { 
    private int i; 
    public A(int x) { 
     i = x; 
    }@ 
    Override 
    public void run() { 
     System.out.println(i); 
    } 
} 

/**主**/

A c1 = new A(5); 
A c2 = new A(6); 
Semaphore s = new Semaphore(1, true); 
c1.start(); 
c2.start(); 

new Thread(new Runnable() { 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) {} 
      System.out.println("+"); 
     } 
    } 
}).start(); 

new Thread(new Runnable() { 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      try { 
       Thread.sleep(70); 
      } catch (InterruptedException e) {} 
      System.out.println("*"); 
     } 

    } 
}).start(); 
+2

一个其他=连续之后。为什么你想要多个线程? –

+0

为了行使我在控制线程 – Csi

+2

这没有任何意义。开始第一个线程。 '加入'就可以了。然后'开始'第二个线程。然后'加入'。这里没有理由使用“信号量”。 –

回答

0
  • 我想知道怎样才能让这些线程的工作一个接一个,和
  • 如何让第一个总是在第二个之后运行。我创建了一个信号量,但我不确定如何使用它。

如果你想线程调用线程C2之前完成你可以在你的情况下使用join()。像这样(的主题被称为在main线程):

c1.start(); // Start thread `c1` first 
c1.join(); // `main` now waits for `c1` to finish 
c2.start(); // Start thread `c2` next 
c2.join(); // `main` now waits for `c2` to finish 

这应该回答你的问题。

我关于信号量的一点点。

一般来说,您不能使用信号量来控制线程的执行顺序。信号量是一个或多个资源的锁。希望访问资源的线程彼此竞争,您无法控制信号量接下来将授予访问权限的用户。

我知道其他答案中的“诡计”。我没有测试它,它可能工作,但我不认为这是做到这一点的正确方法。

这里是没有sempahore工作的例子:

import java.util.concurrent.Semaphore; 

class A extends Thread { 

    private int i; 
    public A(int x) { 
     i = x; 
    } 

    public void run() { 
     System.out.println(i); 
    } 

    public static void main(String[] args) throws Exception { 
     A thread1 = new A(5); 
     A thread2 = new A(6); 
     thread1.start(); 
     thread1.join(); 
     thread2.start(); 
     thread2.join(); 
    } 
} 

如果你想使用一个信号量(虽然我不明白为什么),那么例如可以是这样的:

import java.util.concurrent.Semaphore; 

class A extends Thread { 

     private int i; 
     final static Semaphore semaphore = new Semaphore(1, true); 

     public A(int x) { 
      i = x; 
     } 

     public void run() { 
      try { 

       /*thread stops here until it gets permit to go on*/ 
       semaphore.acquire(); 
       System.out.println(i); 
      /*exception must be caught or thrown*/ 
      } catch (InterruptedException e) { } 

      //CRITICAL SECTION 

      semaphore.release(); 

     } 

    public static void main(String[] args) throws Exception { 
     A thread1 = new A(5); 
     A thread2 = new A(6); 
     thread1.start(); 
     thread1.join(); 
     thread2.start(); 
     thread2.join(); 
    } 
} 
+0

Sry,我不在家。在我的例子中,有可以用join()组织的c1和c2线程;如你所说。现在我懂了。但是主体中还有两个“新线程”执行自己。这里需要信号量,因为没有使用join()方法的实例名称。用你的例子,我也设法控制它们,谢谢你,先生。 – Csi

+0

在这种情况下,请使用具有公平选项的二进制信号量。如果它帮助你解决问题,请随时注意并接受答案。 – Elyasin

0

可以在信号量许可证模型来表示: “允许运行”。

由于您希望允许第一个线程自动运行,因此第一个线程不能使用acquire,因为它将与第二个线程竞争许可。所以第一个线程开始,假设它有许可证。当第一个线程完成时,它是release-是许可证。第二个线程需要acquire许可才能开始工作。

首先创建零个许可

final Semaphore s = new Semaphore(0, true); 

(因为一个许可证已经被隐含的第一个线程拥有)在第一线中的最后一行应改为旗语:

s.release(); 

(注它允许在没有获得的情况下发布 - 信号量只是计数,它不记录哪个拥有哪个许可)

而第二个线程中的第一行应改为:

s.acquireUninterruptibly(); 

(或只是acquire()但随后你需要赶上InterruptedException

0

尽管你的问题可以通过 可以强制完成一个线程的“连接”功能来解决,但在开始下一个asi之前(如图所示) Elyasian的例子,但仍然必须补充说明你在右边跟踪 就信号量航线而言。

信号量s =新的信号量(1,true);

在本声明中,将第二个参数设置为“true”被称为公平设置。

这确保(FIFO - 先进先出)在我们的场景换句话说,“先到先得” ......

即调用获得第一将获得许可,将完成 线程其任务第一,然后第二个线程将能够执行 它的执行。

所以你原来的问题.....即

我想知道我怎样才能使这些线程的工作一个接一个,以及如何使第一个总是第二个

后运行

的措词,

我想知道我怎样才能确保调用线程获得 首先在信号到达第一始终运行....