5

我是多线程的新手,当我阅读有关多线程的内容时,想到编写这个花哨的多线程代码来执行以下操作。

我的计数器类如下。

class Counter {
  private int c = 0;

  public void increment() {
    System.out.println("increment value: "+c);
      c++;
  }

  public void decrement() {
      c--;
      System.out.println("decrement value: "+c);
  }

  public int value() {
      return c;
  }

}

此 Counter 对象在两个线程之间共享。启动线程后,我需要执行以下操作。我希望 Thread2 等到 Thread1 将 Counter 对象的计数增加 1。完成后,线程 1 通知 thread2,然后 Thread1 开始等待 thread2 将值减 1。然后 thread2 启动并将值减 1 和再次通知thread1,然后thread2开始等待thread1。重复这个过程几次。

我怎样才能做到这一点。提前谢谢了。

我做了以下事情。

public class ConcurrencyExample {

  private static Counter counter;
  private static DecrementCount t1;
  private static IncrementCount t2;

  public static void main(String[] args) {
    Counter counter = new Counter();
    Thread t1 = new Thread(new IncrementCount(counter));
    t1.start();

    Thread t2 = new Thread(new DecrementCount(counter));
    t2.start();

  }

}


public class DecrementCount implements Runnable {

  private static Counter counter;

  public DecrementCount(Counter counter) {
    this.counter = counter;
  }

  @Override
  public void run() {
    for (int i = 0; i < 1000; i++) {
      counter.decrement();     
      System.out.println("decreamented");
    }
  }

}


public class IncrementCount implements Runnable {

  private static Counter counter;

  public IncrementCount(Counter counter) {
    this.counter = counter;
  }

  @Override
  public void run() {
    for (int i = 0; i < 1000; i++) {
      counter.increment();
      System.out.println("Incremented");
    }

  }

}
4

4 回答 4

3

退房Semaphore。您需要两个,每个线程一个:incSemaphoredecSemaphore. 在DecrementCount做:

for (int i = 0; i < 1000; i++) {
  decSemaphore.acquire();
  counter.decrement();     
  System.out.println("decreamented");
  incSemaphore.release();
}

IncrementCount对称实施。的初始值incSemaphore应该是10for decSemaphore

顺便说一句,您Counter也需要同步(请参阅synchronized关键字 and AtomicInteger)。

于 2012-09-25T16:16:07.107 回答
0

使用带有布尔标志的条件。

final Lock lock = new ReentrantLock();
final Condition incremented= lock.newCondition(); 
final Condition decremented= lock.newCondition(); 

将您的计数器更改为以下

解释 :

我们使用了两个条件,一个是递增的,一个是递减的。基于布尔标志,我们检查是否必须等待一个条件。

 class Counter {
private int c = 0;
boolean increment = false;

final Lock lock = new ReentrantLock();
final Condition incremented = lock.newCondition();
final Condition decremented = lock.newCondition();

public void increment() throws InterruptedException {
    Lock lock = this.lock;
    lock.lock();
    try {
        while(increment)
            decremented.await();
        increment = true;           
        c++;
        System.out.println("increment value: " + c);
        incremented.signal();
    } finally {
        lock.unlock();
    }

}

public void decrement() throws InterruptedException {

    Lock lock = this.lock;
    lock.lock();
    try {
        while (!increment)
            incremented.await();
        c--;
        System.out.println("decrement value: " + c);
        increment = false;
        decremented.signal();
    } finally {
        lock.unlock();
    }
}

public int value() {
    Lock lock = this.lock;
    lock.lock();
    try {
        return c;
    } finally {
        lock.unlock();
    }
}

}
于 2012-09-25T16:12:44.013 回答
0

同步器使线程能够相互等待。请参阅CountDownLatchSemaphore

请参阅 java.util.concurrent 包中的同步器部分

于 2012-09-25T16:17:00.350 回答
0

-首先你必须使用关键字increment()来避免竞争条件参见这个布赖恩的规则decrement()synchronized

When we write a variable which has just been read by another thread, or reading a variable which is just lately written by another thread, must be using Synchronization. And those atomic statements/Methods accessing the fields' data must be also synchronized.

-JVM Thread Scheduler可以控制哪个线程将进入运行状态,它会在那里停留多长时间,以及它在工作完成后会去哪里。

-其中一个Cannot be sure线程将首先运行.....

-您也可以使用SingleThreadExecutorfrom java.util.concurrent,这将完成一项任务,然后再进行第二项任务。

于 2012-09-25T16:24:12.723 回答