2015-02-05 125 views
-1

从以下代码:多线程队列的java

public class Main { 
    static String[] s = { "aaaaaaa", "bbbb", "ccc", "dd" }; 

    public static void main(String[] args) { 
     Watek w = new Watek(0); 
     Watek w1 = new Watek(1); 
     Watek w2 = new Watek(2); 
     Watek w3 = new Watek(3); 
     w.start(); 
     w1.start(); 
     w2.start(); 
     w3.start(); 

    } 

} 

class Watek extends Thread { 
    int i; 

    public Watek(int i) { 
     this.i = i; 
    } 

    public void run() { 
     for (int j = 0; j < Main.s[i].length(); j++) { 
      System.out.print(Main.s[i].charAt(j) + " "); 
     } 

    } 

} 

我看到控制台

A A A A B B B B等。

但我需要:

abcdabc d ...

我尝试使用wait();notify();, synchronized,但我仍然有AAAA或错误

谁能告诉我,我需要怎么去做这个 ??

+0

这对我没有意义。你能描述一下你真正想要的吗? – displayname 2015-02-05 17:57:29

+3

这比你想象的更复杂,你需要使用'ThreadPool'并实现'算法'来阻止和等待。 'Thread'的正常'wait'函数不会这样做。 – 2015-02-05 17:58:51

+0

我需要在控制台abcdabcdab ....上写字符串[] s = {“aaaaaaa”,“bbbb”,“ccc”,“dd”};我只能用一个字母来代替一个字母(一个用于a,一个用于b,一个用于c .....) – Mokbor 2015-02-05 18:20:27

回答

0

wait,​​和notifyAll将解决你的问题。

而不是使用单Thread类的,我会建议你使用4个不同势Thread类各1个字母

这里是工作示例中,只要是完整的代码

public class Main { 
    static String[] s = { "aaaaaaa", "bbbb", "ccc","ddd"}; 
    static int status=1; // For Maintaning Order Of Processing of Threads 

    public static void main(String[] args) { 

     Main m=new Main(); // This Object's Lock is used by threads 

     Watek1 w1 = new Watek1(0,m); 
     Watek2 w2 = new Watek2(1,m); 
     Watek3 w3 = new Watek3(2,m); 
     Watek4 w4 = new Watek4(3,m); 

     w1.start(); 
     w2.start(); 
     w3.start(); 
     w4.start(); 

    } 

} 

class Watek1 extends Thread { 
    int i; 
    Main main; 
    public Watek1(int i,Main main) { 
     this.i = i; 
    this.main=main; 
    } 

    public void run() { 
    try 
    { 
     synchronized(main) 
     { 
       for (int j = 0; j < Main.s[i].length(); j++) 
     { 
        while(main.status!=1) 
        { 
         main.wait();  
        } 
        main.status=2; 
        System.out.print(Main.s[i].charAt(j) + " "); 
        main.notifyAll(); 
      } 
     } 
     } 
     catch(Exception e) 
     { 
     e.printStackTrace();  
     } 

    } 

} 
class Watek2 extends Thread { 
    int i; 
    Main main; 
    public Watek2(int i,Main main) { 
     this.i = i; 
    this.main=main; 
    } 

    public void run() { 

    try 
    { 
     synchronized(main){ 
     for (int j = 0; j < Main.s[i].length(); j++) { 
     while(main.status!=2) 
     { 
      main.wait();  
     } 

      System.out.print(Main.s[i].charAt(j) + " "); 
     main.status=3; 
     main.notifyAll(); 
     } 

    } 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace();  
    } 
    } 


} 
class Watek3 extends Thread { 
    int i; 
    Main main; 
    public Watek3(int i,Main main) { 
     this.i = i; 
    this.main=main; 
    } 

    public void run() { 
    try 
    { 
    synchronized(main){ 
     for (int j = 0,counter=0; j < Main.s[i].length(); j++) { 
     while(main.status!=3) 
     { 
      main.wait();  
     } 

      System.out.print(Main.s[i].charAt(j) + " "); 
     main.status=4; 
     main.notifyAll(); 
     } 


    } 
     } 
    catch(Exception e) 
    { 
     e.printStackTrace();  
    } 

    } 

} 

class Watek4 extends Thread { 
    int i; 
    Main main; 
    public Watek4(int i,Main main) { 
     this.i = i; 
    this.main=main; 
    } 

    public void run() { 
    try 
    { 
    synchronized(main){ 
     for (int j = 0,counter=0; j < Main.s[i].length(); j++) { 
     while(main.status!=4) 
     { 
      main.wait();  
     } 

      System.out.print(Main.s[i].charAt(j) + " "); 
     main.status=1; 
     main.notifyAll(); 
     } 


    } 
     } 
    catch(Exception e) 
    { 
     e.printStackTrace();  
    } 

    } 

} 

输出

a b c d a b c d a b c d a b 

基本概念/逻辑后面这是,虽然1个线程执行其他线程必须等待,一旦1个线程完成它的处理它改变了状态,并且还notifyAll线程内等待池所以能够其它线程来执行。

和状态计数器是循环为了

1------------2 
|   | 
|   | 
|   | 
|   | 
4------------3 
+0

什么是“状态计数器是循环打印的顺序”应该是什么意思? – specializt 2015-02-05 19:17:57

+0

在每个线程类中,我将状态更改为下一个状态,并且在最后一个线程中,我将该计数器再次设置为1以便线程1再次开始执行,希望它清除它应该表示的内容 – 2015-02-05 19:23:17

+0

谢谢,它可以,但是是固定的4个字母,我需要保护我的程序超过4个字母,当我采取10个lestters我需要创建6个线程更多。在你的想法是一个小问题,你最终需要更多 – Mokbor 2015-02-05 19:44:50

0

使用@Neeraj代码打印终于我有我想要的东西。 如果有人有同样的问题,我把我的代码:

import java.util.ArrayList; 

public class Main { 
    static String[] s = { "aaaaa","bbbb", "ccc", "dd" ,"e"}; 
    static ArrayList<Integer> lista = new ArrayList<Integer>(); 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     Main m = new Main(); 
     ArrayList<Thread> watki = new ArrayList<Thread>(); 

     lista.add(0); 
     for(int i =0;i<s.length;i++){ 
      watki.add(new Watek(i,m)); 
      lista.add(i); 
     } 
     for(int i=0;i<watki.size();i++){ 
      watki.get(i).start(); 
     } 
     lista.remove(0); 

    } 

} 


class Watek extends Thread { 
    int i; 
    Main main; 

    public Watek(int i, Main main) { 
     this.i = i; 
     this.main= main; 
    } 

    public void run() { 
     synchronized (main) { 

      for (int j = 0; j < Main.s[i].length(); j++) { 
       while (main.lista.get(0) != i) { 
        try { 
         main.wait(); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
       if(j<Main.s[i].length()-1) 
       main.lista.add(i); 
       main.lista.remove(0); 
       System.out.print(Main.s[i].charAt(j) + " "); 
       main.notifyAll(); 
      } 

     } 

    } 

}