Порядковый номер с использованием потока синхронизации

1

Я хочу напечатать серию из 1 до 100 чисел, используя n количество потоков (для этого требуется 10 потоков). Условие 1-й нити будет иметь порядковый номер от 1, 11,21.... 91, вторая нить будет иметь последовательность 2,12,22..... 92 и так далее. Все остальные потоки будут иметь порядковый номер, подобный этому. Теперь я хочу напечатать номер в последовательности от 1 до 100. Я знаю, что мы можем использовать синхронизацию, ждать и уведомлять метод и использовать счетчик переменных или флагов, но я не думаю, что это хорошая идея его использовать. Я хочу использовать без параллелизма (например, исполнители и т.д.), Как я это сделаю. Пожалуйста, предложите.

public class PrintNumberSequenceUsingRunnable {
    int notifyValue = 1;

    public static void main(String[] args) {
        PrintNumberSequenceUsingRunnable sequence = new PrintNumberSequenceUsingRunnable();
        Thread f = new Thread(new First(sequence), "Fisrt");
        Thread s = new Thread(new Second(sequence), "Second");
        Thread t = new Thread(new Third(sequence), "Third");
        f.start();
        s.start();
        t.start();
    }
}

class First implements Runnable {
    PrintNumberSequenceUsingRunnable sequence;

    public First(PrintNumberSequenceUsingRunnable sequence) {
        this.sequence = sequence;
    }

    @Override
    public void run() {
        printFist();
    }

    private void printFist() {
        synchronized (sequence) {
            for (int i = 1; i <= 20; i += 3) {
                while (sequence.notifyValue != 1) {
                    try {
                        sequence.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
                sequence.notifyValue = 2;
                sequence.notifyAll();
            }
        }
    }
}

class Second implements Runnable {
    PrintNumberSequenceUsingRunnable sequence;

    public Second(PrintNumberSequenceUsingRunnable sequence) {
        this.sequence = sequence;
    }

    @Override
    public void run() {
        printSecond();
    }

    private void printSecond() {
        synchronized (sequence) {
            for (int i = 2; i <= 20; i += 3) {
                while (sequence.notifyValue != 2) {
                    try {
                        sequence.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
                sequence.notifyValue = 3;
                sequence.notifyAll();
            }
        }
    }

}

class Third implements Runnable {
    PrintNumberSequenceUsingRunnable sequence;

    public Third(PrintNumberSequenceUsingRunnable sequence) {
        this.sequence = sequence;
    }

    @Override
    public void run() {
        printThrid();
    }

    private void printThrid() {
        synchronized (sequence) {
            for (int i = 3; i <= 20; i += 3) {
                while (sequence.notifyValue != 3) {
                    try {
                        sequence.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName() + " " + i);
                sequence.notifyValue = 1;
                sequence.notifyAll();
            }
        }
    }
}
  • 0
    В качестве упражнения ваша проблема определенно интересна. Но я надеюсь, вы понимаете, что вы хотите сериализовать все исполнения и привести их в порядок, что противоречит цели многопоточности.
  • 0
    Вы разместили код, который, на первый взгляд, кажется, делает то, что вы описываете; так что я действительно не понимаю, в чем ваш вопрос. У вас есть ошибка компиляции или какая-то ошибка?
Показать ещё 1 комментарий
Теги:
multithreading
synchronized

1 ответ

1
Лучший ответ

Вам нужно иметь значения, отсортированные по каждому потоку. Каждый раз, когда поток записывает число, он запускает событие в шине событий. Все темы подписаны на мероприятие.

Вы запускаете систему, вызывая событие [минимальное значение - 1].

Каждый поток получит уведомление о том, что значение [минимальное значение - 1] опубликовано. Будет действовать только поток, который имеет значение [минимальное значение] и инициирует новое событие для значения [минимальное значение + 1].

Изменение: я не тестировал его, но что-то вроде этого.

static void main(String[] args) {
    List<Deque<Integer>> publishQueues = new ArrayList<>();
    for (int i = 1; i <= 10; i++) {
        new Thread(new Worker(i, publishQueues)).start();
    }
}

class Worker implements Runnable {
    Deque subscriberQueue;
    List<Deque<Integer>> publishQueues;
    int i;
    Worker(int i, List<Deque<Integer>> publishQueues) {
        this.i = i;
        this.publishQueues = publishQueues;
        this.subscriberQueue = new ConcurrentLinkedDeque<>();
        this.publishQueues.add(this.subscriberQueue);
    }

    void Run() {
        LinkedList<Integer> ints = new LinkedList<>();
        for (int j = i; j <= 100; j+=10) {
            ints.add(j);
        }

        while (true) {
            Integer publishedInteger = subscriberQueue.poll();
            if (publishedInteger == ints.getFirst() - 1) {
                Integer integer = ints.poll();
                System.out.println(integer);
                for (Dequeu<Integer> publishQueue : publishQueues) {
                    publishQueue.addLast(integer);
                }
            }
        }
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню