2012-12-17 56 views
0

我想运行这个java代码,但它不能正常工作。用JAVA控制信号线程访问

请让我知道我做错了什么。

for循环有我少于10 ;.该程序工作正常,如果它的i小于1(表示无环),但(我小于n),其中n大于1,它抛出异常

public class Main { 

    public static void main(String[] args) { 
     final Semaphore sem = new Semaphore(1, true); 
     Thread t1 = new Thread("TA") { 
      public void run() { 
       try { 
        sem.acquire(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println("A"); 
       sem.release(); 
      } 
     }; 
     Thread t2 = new Thread("TB") { 
      public void run() { 
       try { 
        sem.acquire(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println("B"); 
       sem.release(); 
      } 
     }; 
     Thread t3 = new Thread("TC") { 
      public void run() { 
       try { 
        sem.acquire(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println("C"); 
       sem.release(); 
      } 
     }; 

     for (int i = 0; i < 10; i++) { 
      t1.start(); 
      t3.start(); 
      t2.start(); 
     } 

    } 
} 

回答

1

不能启动一个线程不止一次。所以在第二次循环中,第二次调用t1.start()时会发生异常。这是javadoc中说明:

多次启动线程永远不合法。特别是,线程一旦完成执行就不会重新启动。

抛出:IllegalThreadStateException - 如果线程已经启动。

您可以使用ExecutorService而不是直接操作线程。它看起来是这样的:

public static void main(String[] args) throws Exception { 
    ExecutorService executor = Executors.newFixedThreadPool(3); 
    final Semaphore sem = new Semaphore(1, true); 
    Runnable r1 = new Runnable() { 
     public void run() { 
      try { 
       sem.acquire(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("A"); 
      sem.release(); 
     } 
    }; 
    Runnable r2 = new Runnable() { 
     public void run() { 
      try { 
       sem.acquire(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("B"); 
      sem.release(); 
     } 
    }; 
    Runnable r3 = new Runnable() { 
     public void run() { 
      try { 
       sem.acquire(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("C"); 
      sem.release(); 
     } 
    }; 

    for (int i = 0; i < 10; i++) { 
     executor.submit(r1); 
     executor.submit(r2); 
     executor.submit(r3); 
    } 

    executor.shutdown(); 
} 
+0

是准确 所以我应该怎么做,如果我想要一个线程超过一次 –

+0

@Asadullah使用线程poolhttp做一个任务://docs.oracle.com/javase /tutorial/essential/concurrency/pools.html或者只为循环的每一行创建新线程 –

+0

您可以在每个“run”方法内循环,或者为每个任务使用一个线程,或者使用Executor并提交几个相同的任务倍。 – assylias