2014-10-16 89 views
3

我正在学习Java,但遇到同步问题。我想从许多Java线程打印数字列表,并让每个线程按顺序排列。我在使用synchronized时遇到问题,因为我不太了解。可以帮助理解?Java基本同步线程

我想输出看到这一点,但有时错order.i线程想:

1-thread1 
2-thread2 
3-thread1 
4-thread2 
5-thread1 
6-thread2 
... 
48-thread2 
49-thread1 

我破碎的代码:

public class ManyThreadsAdd { 
    public static int index = 0; 

    public static void main(String[] args) { 
     ManyThreadsAdd myClass = new ManyThreadsAdd(); 
     Thread thread1 = new Thread(myClass.new RunnableClass()); 
     Thread thread2 = new Thread(myClass.new RunnableClass()); 

     thread1.start(); 
     thread2.start(); 
    } 

    class RunnableClass implements Runnable { 
     public synchronized void run() { 
      while (index < 49) { 
       try { 
        Thread.sleep(100); 
        System.out.println(index+"-" +Thread.currentThread()); 
        index = index + 1; 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
+1

你必须使用'等待()'和'通知()'这里。你需要线程之间的某种通信来实现你的输出。 – TheLostMind 2014-10-16 14:18:39

+0

是的,我尝试等待并通知,但总是错误的例外。也许普通的班级使用wait和notify? – JoeJoeJoeJoe4 2014-10-16 14:39:40

+0

你必须使用共享锁。请参阅http://stackoverflow.com/q/6017281/217324的接受答案。投票结束,因为这是同样的问题。我试着为你选择一个好的,但如果这不能解决你的问题,有很多其他问题发布在这个问题上有答案,谷歌为“Java多线程甚至奇怪的网站:stackoverflow.com”。 – 2014-10-16 15:11:44

回答

2

这取决于你想要做什么。

交替打印顺序的一种简单方法是在同一个对象上进行同步,在这种情况下,您可以使用索引或任何其他对象。

public class ManyThreadsAdd { 
    public static AtomicInteger index = new AtomicInteger(0); 

    public static void main(String[] args) { 
     ManyThreadsAdd myClass = new ManyThreadsAdd(); 
     Thread thread1 = new Thread(myClass.new RunnableClass()); 
     Thread thread2 = new Thread(myClass.new RunnableClass()); 

     thread1.start(); 
     thread2.start(); 
    } 

    class RunnableClass implements Runnable { 
     public void run(){ 
      synchronized(index){ 
       while(index.get() < 49){ 
        try { 
         Thread.sleep(100); 
         System.out.println(index.get()+"-" +Thread.currentThread()); 
         index.incrementAndGet(); 
         index.notify(); 
         index.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    } 
} 
+0

这个我明白最好。容易看到原子增量,然后通知()和等待()。谢谢 – JoeJoeJoeJoe4 2014-10-16 18:16:15

2

首先,多线程本质上是异步的,你不能指定这些线程执行的顺序。如果你想要像下面的输出,使用循环:

1-thread1 
2-thread2 
3-thread1 
4-thread2 
5-thread1 
6-thread2 
... 
48-thread2 
49-thread1 

其次,可以通过在public synchronized void run()加入​​关键字一无所获。这意味着在任何时候,一次只有一个线程可以调用该方法。当你为每个线程构造新的类时,这是没有意义的。

第三,如果您确实需要在您的线程之间进行同步,请使用您添加任务的队列以及您的线程一次读取的队列。

+0

你总是打开新的RunnableClass,所以不会有同步。 做单身课。 – 2014-10-16 14:20:11