线程吃和醒来

时间:2014-09-11 10:39:21

标签: java multithreading concurrency

我试图更好地理解线程,所以我正在实现一个简单的任务:

我有两个实现runnable的类。每个从1到10生成2个随机整数.ClassA计算总和,ClassB计算乘法。两人都在循环中完成这项工作15秒。

我有另一个名为General的类,它有2个静态和同步方法:setVal和getVal。每个线程在每次计算/迭代后调用General.setVal(result)。 setVal仅在值更接近于其先前值的数字时设置该值。 getValue只获取值。

我有一个启动每个线程的主类。然后有一个循环,持续20秒输出线程设置的值。所以它只是调用getValue并打印它。

我希望每个线程在一次迭代后等待并通知另一个进行迭代等等......我该怎么做?

这是我的代码:

public class Particle1 implements Runnable{

    //private int x;
    private static final int max = 10;
    private static final int min = 1;

    public void run(){
        long t= System.currentTimeMillis();
        long end = t+15000;
        while(System.currentTimeMillis() < end) {
           Random rand = new Random();
           int a = rand.nextInt((max - min) + 1) + min;
           int b = rand.nextInt((max - min) + 1) + min;

           int x = a+b;
           System.out.println("P1: "+a+"+"+b+"="+x);
           Gather.setRes(x);
           //i want it here to sleep until the other one wakes it up.
       }
    }

}


public class Particle2 implements Runnable{

    //private int x;
    private static final int max = 10;
    private static final int min = 1;

    public void run(){
        long t= System.currentTimeMillis();
        long end = t+15000;
        while(System.currentTimeMillis() < end) {
            Random rand = new Random();
            int a = rand.nextInt((max - min) + 1) + min;
            int b = rand.nextInt((max - min) + 1) + min;

            int x = a+b;             
            System.out.println("P2: "+a+"+"+b+"="+x);
            Gather.setRes(x);
            //i want it here to sleep until the other one wakes it up.
         }
    }

}


public class Main {

    public static void main(String[] args) throws InterruptedException {

        Thread thread1 = new Thread(new Particle1());
        Thread thread2 = new Thread(new Particle2());
        thread1.start();
        thread2.start();


        long t= System.currentTimeMillis();
        long end = t+20000;
        while(System.currentTimeMillis() < end) {
            System.out.println("Minimum is: "+Gather.getRes());
            Thread.sleep(1000);
        }
        return;
    }

}


public class Gather {

    public Gather() {
        // TODO Auto-generated constructor stub
    }

    private static int res=1000000;

    public static int getRes() {
        return res;
    }

    public synchronized static void setRes(int inres) {
        if(Math.abs(inres-250)<res){
            res = inres;
        }
    }



}

1 个答案:

答案 0 :(得分:1)

当您希望所有线程独立运行而不是彼此锁定时,使用线程通常是一种练习。

但是,有时候线程需要在它们之间进行通信 - 在这种情况下,通常使用某种形式的BlockingQueue来进行通信。这是一个例子:

public class TwoThreads {
  public static void main(String args[]) throws InterruptedException {
    System.out.println("TwoThreads:Test");
    new TwoThreads().test();
  }

  // The end of the list.
  private static final Integer End = -1;

  static class Producer implements Runnable {
    final Queue<Integer> queue;

    public Producer(Queue<Integer> queue) {
      this.queue = queue;
    }

    @Override
    public void run() {
      try {
        for (int i = 0; i < 1000; i++) {
          queue.add(i);
          Thread.sleep(1);
        }
        // Finish the queue.
        queue.add(End);
      } catch (InterruptedException ex) {
        // Just exit.
      }
    }

  }

  static class Consumer implements Runnable {
    final Queue<Integer> queue;

    public Consumer(Queue<Integer> queue) {
      this.queue = queue;
    }

    @Override
    public void run() {
      boolean ended = false;
      while (!ended) {
        Integer i = queue.poll();
        if (i != null) {
          ended = i == End;
          System.out.println(i);
        }
      }
    }

  }

  public void test() throws InterruptedException {
    Queue<Integer> queue = new LinkedBlockingQueue<>();
    Thread pt = new Thread(new Producer(queue));
    Thread ct = new Thread(new Consumer(queue));
    // Start it all going.
    pt.start();
    ct.start();
    // Wait for it to finish.
    pt.join();
    ct.join();
  }

}

要真正在两个线程之间同步,您可以使用相同的机制,但使用SynchronousQueue代替。