需要产生很多线程。每个线程都执行一样的任务,比如调用某种资源。不过不是每个线程都能顺利执行至结束的,所以没有成功的线程我想把它放到一个队列Queue里(比如用linkedlist来实现),然后按照固定的时间,比如每5秒钟后,从队列里拿出最前面的那个线程再去执行当时失败的任务。具体如何做才能实现这个过程那?开始想到需要把失败的线程暂停,然后把线程对象放到队列里,等队列中前面的都执行完了,再重新激活这个线程再去尝试执行原来的任务。可是发现线程的suspend等都不能用。那我可以在线程的RUN部分的代码里,如果发现执行失败,就在退出线程代码前加上 queue.addLast(this)么?这样能把这个线程对象加到队列里来么,等到再取出来时,会执行一样的功能?或者有更好的解决方案?谢谢!

解决方案 »

  1.   

    Use the Event queue to retrieve event 
    import java.awt.AWTEvent;
    import java.awt.Container;
    import java.awt.EventQueue;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;public class EventQueuePanel extends JPanel implements ActionListener {
      EventQueuePanel() {
        JButton button = new JButton("Draw line");
        add(button);
        button.addActionListener(this);
      }  public void actionPerformed(ActionEvent evt) {
        Graphics g = getGraphics();    displayPrompt(g, "Click to chooose the first point");
        Point p = getClick();
        g.drawOval(p.x - 2, p.y - 2, 4, 4);
        displayPrompt(g, "Click to choose the second point");
        Point q = getClick();
        g.drawOval(q.x - 2, q.y - 2, 4, 4);
        g.drawLine(p.x, p.y, q.x, q.y);
        displayPrompt(g, "Done! Press button the start again.");
        g.dispose();
      }  public void displayPrompt(Graphics g, String s) {
        y += 20;
        g.drawString(s, 0, y);
      }  public Point getClick() {
        EventQueue eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
        while (true) {
          try {
            AWTEvent evt = eq.getNextEvent();
            if (evt.getID() == MouseEvent.MOUSE_PRESSED) {
              MouseEvent mevt = (MouseEvent) evt;
              Point p = mevt.getPoint();
              Point top = getRootPane().getLocation();
              p.x -= top.x;
              p.y -= top.y;
              return p;
            }
          } catch (InterruptedException e) {
          }
        }
      }  private int y = 60;
      public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setTitle("EventQueueTest");
        frame.setSize(300, 200);
        frame.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });    Container contentPane = frame.getContentPane();
        contentPane.add(new EventQueuePanel());    frame.show();
      }}
      

  2.   

    Queue data structure 
    public class Queue {
      private int maxSize;  private long[] queArray;  private int front;  private int rear;  private int nItems;  public Queue(int s) {
        maxSize = s;
        queArray = new long[maxSize];
        front = 0;
        rear = -1;
        nItems = 0;
      }  //   put item at end of a queue
      public void insert(long j) {
        if (rear == maxSize - 1) // deal with wraparound
          rear = -1;
        queArray[++rear] = j; // increment rear and insert
        nItems++; 
      }  //   take item from front of queue
      public long remove() {
        long temp = queArray[front++]; // get value and incr front
        if (front == maxSize) // deal with wraparound
          front = 0;
        nItems--; // one less item
        return temp;
      }  public long peekFront() {
        return queArray[front];
      }  public boolean isEmpty() {
        return (nItems == 0);
      }  public boolean isFull() {
        return (nItems == maxSize);
      }  public int size() {
        return nItems;
      }  public static void main(String[] args) {
        Queue theQueue = new Queue(5); // queue holds 5 items    theQueue.insert(10);
        theQueue.insert(20);
        theQueue.insert(30);
        theQueue.insert(40);    theQueue.remove(); 
        theQueue.remove(); 
        theQueue.remove();    theQueue.insert(50); 
        theQueue.insert(60); //    (wraps around)
        theQueue.insert(70);
        theQueue.insert(80);    while (!theQueue.isEmpty()) {
          long n = theQueue.remove(); // (40, 50, 60, 70, 80)
          System.out.print(n);
          System.out.print(" ");
        }
        System.out.println("");
      }
    }
      

  3.   

    “在线程的RUN部分的代码里,如果发现执行失败,就在退出线程代码前加上 queue.addLast(this)么“刚这样试了,这线程对象倒是加到队列Queue里了,也能够取出来,判断状态isAlive()也是false,可是不能再执行start(),抛出java.lang.IllegalThreadStateException错误。看来一个线程被执行后,就是存起来也没法再用的那怎么办哪?
      

  4.   

    你要实现 没有成功的线程我想把它放到一个队列Queue里(比如用linkedlist来实现),然后按照固定的时间,比如每5秒钟后,从队列里拿出最前面的那个线程再去执行当时失败的任务。就不能在失败的时候,让此线程的run方法返回,
    如果返回了,你对这个线程再调用.start()也是没有的,线程不会再次被启动。
      

  5.   

    "就不能在失败的时候,让此线程的run方法返回"可是这样没法做到阿。原来以为设置一个无限循环就好了,一次失败了后,就放到队列里,等取出来时恢复执行,就开始重新执行循环(该做的任务),否则,成功就结束run方法。可是没法将一次失败的线程暂停,,,suspend不能用
      

  6.   

    也许你应该把你的问题具体化一下。看下下面的代码,public class ThreadTest {
    public static void main(String args[]) {
    SimpleOne so = new SimpleOne("bzwm");
    ThreadImpOne tio = new ThreadImpOne(so);
    new Thread(tio).start();
    }
    }class SimpleOne {
    private transient int count = 0; private String name = null; public SimpleOne() {
    } public SimpleOne(String n) {
    setName(n);
    } public int getCount() {
    return count;
    } public void setCount(int count) {
    this.count = count;
    } public String getName() {
    return name;
    } public void setName(String name) {
    this.name = name;
    } public void test() throws Exception {
    //这里模拟任务失败,即第一次执行时失败。
    if (count == 0) {
    count++;
    throw new Exception();
    } else {
    System.out.println("hello " + name);
    }
    }
    }class ThreadImpOne implements Runnable { SimpleOne so = null; public ThreadImpOne(SimpleOne s) {
    so = s;
    } public void run() {
    try {
    //如果test方法抛出异常,则认为任务失败了。
    so.test();
    } catch (Exception e) {
    try {
    synchronized (so) {
    so.wait(3000);
    }
    //这里继续执行run(),直到可以成功,但在失败的时候,并没有让run方法返回
    run();
    } catch (InterruptedException e1) { }
    }
    }
    }
      

  7.   

    楼主应该重新思考一下设计,这跟队列没有什么关系。用一个 Vector 保存线程执行的参数,每启动一个线程就从中取出一个参数。线程执行失败的话,将参数重新放进 Vector 里面就可以了。