Kilka wątków w jednej pętli, synchronizacja

0

Witam,
Jestem świeży w współbierzności i natrafiłem na pewien problem.

Otóż w metodzie run() mam pętlę, która musi się wykonać x razy ( różne z każdym ponownym uruchomieniem programu ). Startuję 5 wątków, i każdy z nich korzysta z tej pętli w metodzie run(). I teraz moje pytanie, w jaki sposób mam to zrobić, aby po wykonaniu x razy, wszystkie wątki przestały pracować i pętla nigdy więcej nie była wykonana? Próbowałem to zrobić na takiej zasadzie, że w pętli zmienna jest statyczna, tak aby wszystkie wątki korzystały z tej samej, ale to nie podziałało. Prosiłbym o przykład takiej pętli. Dzięki !

0

Najprościej będzie współbieżną referencją przez pajpa, a potem już tylko emaksem przez sendmejl.

0

Dostęp do licznika wykonań pętli powinien być w tym przypadku synchronizowany zarówno dla odczytów, jak i zapisów. W tym celu możesz użyć ReentrantLocka.

Przykład:

import java.util.concurrent.locks.ReentrantLock;

public class Sample implements Runnable {

    // nasz obiekt do synchronizacji dostepu do maxIerations/worksSoFar 
    private static ReentrantLock lock = new ReentrantLock();

    // max. ilosc wywolan petli 
    private static Integer maxIterations = 0;

    // tyle razy wykonano petle
    private static Integer workSoFar = 0;

    @Override
    public void run() {
        // liczbe wykonan jaka zaobserwowal watek -> "consistent read"
        long workSoFarSynchRead = 0;

        // tyle razy petla wykonana przez biezacy watek
        int workByCurrentThread = 0;

        boolean done = false;
        long sleepTime = 0;

        System.out.printf("%s :: Thread started\n", Thread.currentThread());

        while (!done) {
            // staramy sie zrobic bardzo krotka sekcje krytyczna
            lock.lock();
            if (workSoFar < maxIterations) {
                workSoFar++;
                workSoFarSynchRead = workSoFar;
            } else {
                done = true;
            }
            lock.unlock();

            // logika do wykonania
            if (!done) {
                try {
                    workByCurrentThread++;
                    sleepTime = (long) (Math.random() * 500);
                    System.out.printf("%s :: #AllIterations=%d, #IterationsByThread=%d. Working for next [%d] ms\n", Thread.currentThread(), workSoFarSynchRead, workByCurrentThread, sleepTime);
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    // ignore
                }
            }
        }
        System.out.printf("%s :: Thread finished\n", Thread.currentThread());
    }

    public static void main(String[] args) {
        // tyle watkow bedzie pracowac
        int workersCount = 5;

        // tyle iteracji petli chcemy 
        maxIterations = 20;

        // uruchamiamy watki 
        for (int i = 0; i < workersCount; i++) {
            new Thread(new Sample()).start();
        }

    }
}  

Ćwiczenie badawcze: co się stanie jeśli wątek zostanie przerwany między lock() i unlock() ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1