我试图更好地理解线程,所以我正在实现一个简单的任务:
我有两个实现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;
}
}
}
答案 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代替。