Два счетчика на разных потоках, считая, пока один не будет сделан - PullRequest
0 голосов
/ 07 февраля 2020

Сделать 2 счетчика потоков - от начального до конечного значения. Значение счетчика должно отображаться для каждого счета. Один поток настроен на меньшее значение, чем другой. Когда один из потоков считает заданное значение, другой останавливается и завершает свое выполнение. Это моя задача, поэтому я решил с помощью AtomicBoolean run = new AtomicBoolean (true);

/**
 * Implements {@link Runnable} and his method {@link Runnable#run} to run until stop is set to true
 * and count is less than maxCount.
 */
public class Counter implements Runnable {
    private static final Logger logger = LoggerFactory.getLogger(Counter.class);
    private static final String MAX_COUNT_EXCEPTION_MESSAGE = "maxCount should be bigger than zero!";
    private static final int NUMBER_TO_CHECK_MAX_COUNT_VALIDATION = 1;
    private AtomicBoolean run;
    private int count;
    private int maxCount;

    /**
     * Constructs a counter with zero count and run equal to true with a specified maxCount.
     *
     * @param maxCount of the counter
     * @throws IllegalArgumentException if maxCount is smaller than 1
     */
    Counter(int maxCount, AtomicBoolean run) {
        if (maxCount < NUMBER_TO_CHECK_MAX_COUNT_VALIDATION) {
            throw new IllegalArgumentException(MAX_COUNT_EXCEPTION_MESSAGE);
        }
        this.maxCount = maxCount;
        this.run = run;
    }

    /**
     * Entry point.
     * <p>
     * Runs until run is set to false and count is less than maxCount.
     * <p>
     * On every loop {@link Counter} increment count with 1 and print the count.
     */
    @Override
    public void run() {
        while (count < maxCount && run.get()) {
            incrementCount();
            logger.info(this + " : " + count);
        }
        run.set(false);
    }

    /**
     * Used for obtaining current value for the count.
     *
     * @return count.
     */
    int getCount() {
        return count;
    }

    /**
     * Increment the count.
     */
    private void incrementCount() {
        count++;
    }
}

/**
 * Runs two counters and print the counting for both of them until one reach his maxCount then both are stopped.
 */
public class RunnerTwoCounters {
    private static final Logger logger = LoggerFactory.getLogger(RunnerTwoCounters.class);

    public static void main(String[] args) throws InterruptedException {
        AtomicBoolean run = new AtomicBoolean(true);
        Counter counter1 = new Counter(2, run);
        Thread thread1 = new Thread(counter1);
        Counter counter2 = new Counter(10, run);
        Thread thread2 = new Thread(counter2);
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();

        logger.info(counter1 + " " + counter1.getCount());
        logger.info(counter2 + " " + counter2.getCount());
    }
}

Как я могу заставить ту же самую вещь работать, но без Atomicboolean, просто работать с блокировкой объекта и некоторой синхронизацией на нем?

1 Ответ

0 голосов
/ 07 февраля 2020

Это делает то, что говорит ваш недавний комментарий. Оба потока начинают считать. Когда человек достигает уставки, они оба останавливаются.

public class ThreadCounting {

    int value1;
    int value2;
    volatile boolean flag = true;
    public static void main(String[] args) {
        new ThreadCounting().start();
    }

    public void start() {
        int setPoint = 100;
        Thread begin = new Thread(() -> {

            while(flag && ((value1 = counter1()) <= setPoint)) {
                System.out.println(Thread.currentThread().getName() + "     counter1 = " + value1);         
            }
            flag = false;
        });

        Thread finish = new Thread(() -> {

            while(flag && ((value2 = counter2()) <= setPoint)) {
                System.out.println(Thread.currentThread().getName() +" counter2 = " + value2);
            }
            flag = false;

        });

        begin.start();
        finish.start();

    }
    int val1 = 1;
    public int counter1() {
        return val1++;
    }
    int val2 = 1;
    public int counter2() {
        return val2++;
    }
}

...