Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Задачка с несколькими потоками на свой класс семафоров / 6 сообщений из 6, страница 1 из 1
09.04.2014, 12:00
    #38609586
mr_virtus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задачка с несколькими потоками на свой класс семафоров
Всем привет.

У меня есть программа, которая запускает несколько потоков - читающих и пишущих.
Когда работает писатель - другие писатели/читатели ожидают.
Когда работает читатель/читатели - писатель ожидает.

Мне нужно эту задачу реализовать с помощью своего класса семафор, не используя средства java для синхронизации.

Вот что написал:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
public class MyProg {
    public static void main(String[] args) {
        Database myDB = new Database();
        Reader reader1 = new Reader(1, myDB);
        Reader reader2 = new Reader(2, myDB);
        Reader reader3 = new Reader(3, myDB);
        Reader reader4 = new Reader(4, myDB);
        Reader reader5 = new Reader(5, myDB);
        Writer writer1 = new Writer(1, myDB);
        Writer writer2 = new Writer(2, myDB);
        Writer writer3 = new Writer(3, myDB);
        Writer writer4 = new Writer(4, myDB);
        reader1.start();
        reader2.start();
        reader3.start();
        reader4.start();
        reader5.start();
        writer1.start();
        writer2.start();
        writer3.start();
        writer4.start();
    }
}


class Reader extends Thread {
    public Reader(int r, Database db) {
        readerNum = r;
        server = db;
    }

    public void run() {
        int c;
        for (int i = 1; i <= 3; i++) // It should be while (true)
        {
            napping();
            System.err.println("reader " + readerNum + " wants to read.");

            c = server.startRead();
            System.err.println("reader " + readerNum + " is reading. Reader Count = " + c);
            Database.something();

            c = server.endRead();
        }
    }

    public void napping() {
        try {
            sleep((int) (Math.random() * 5000));
        } catch (InterruptedException e) {
        }
    }

    private Database server;
    private int readerNum;
}


class Writer extends Thread {
    public Writer(int w, Database db) {
        writerNum = w;
        server = db;
    }

    public void run() {
        for (int i = 1; i <= 3; i++) // It should be while (true)
        {
            napping();
            System.err.println("writer " + writerNum + " wants to write.");
            server.startWrite();

            System.err.println("-------------- WRITER " + writerNum + " IS WRITING.");
            Database.something();

            System.err.println("               writer " + writerNum + " is done writing.");
            server.endWrite();
        }
    }

    public void napping() {
        try {
            sleep((int) (Math.random() * 5000));
        } catch (InterruptedException e) {
        }
    }

    private Database server;
    private int writerNum;
}


class Database {
    public Database() {
        readerCount = 0;
        semWriter = new Semaphore(1);
    }

    public static void something() {
        try {
            Thread.sleep((int) (Math.random() * 5000));
        } catch (InterruptedException e) {
        }
    }

    public int startRead() {
        if (readerCount == 0){
            semWriter.P();
        }
        readerCount++;
        return readerCount;
    }

    public int endRead() {
        --readerCount;
        System.err.println("Reader is done reading. Count = " + readerCount);
        if (readerCount == 0){
             semWriter.V();            // if I am the last reader tell all others
        }
        return readerCount;
    }

    public void startWrite() {
        semWriter.P();
     }

    public void endWrite() {
        semWriter.V();
    }

    private int readerCount;    // the number of active readers
    private Semaphore semWriter;
}

class Semaphore {
    private int value;

    Semaphore(int v) {
        value = v;
    }

    public void P() {
        while (value <= 0) ;
        value--;
    }

    public void V() {
        ++value;
    }
    public int getValue(){
        return value;
    }
}



Схема с читателями/писателями работает корректно, но программа периодически зависает. Семафор не атомарный и происходит зацикливание иногда.

Как это с помощью семафора / других средств java(использующихся не для синхронизации) это можно реализовать?

Спасибо
...
Рейтинг: 0 / 0
09.04.2014, 12:47
    #38609705
mr_virtus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задачка с несколькими потоками на свой класс семафоров
mr_virtus,

Прошу прощения, ввел в заблуждение.

Все-таки нужно через такой семафор делать:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
class Semaphore
{
    public Semaphore(int v)
    { value = v; }

    public synchronized void P()
    { value--;
        if (value < 0)
            try
            {wait();}
            catch (InterruptedException e) {}
    }

    public synchronized void V()
    { ++value;
        if (value<=0)
            notify();
    }

    private int value;
}
...
Рейтинг: 0 / 0
09.04.2014, 15:58
    #38610142
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задачка с несколькими потоками на свой класс семафоров
не используя средства java для синхронизации
Хвастун... интересно что ты будешь использовать взамен.
...
Рейтинг: 0 / 0
09.04.2014, 16:33
    #38610211
mr_virtus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задачка с несколькими потоками на свой класс семафоров
mayton,
понял, что погорячился=)
...
Рейтинг: 0 / 0
09.04.2014, 16:43
    #38610224
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задачка с несколькими потоками на свой класс семафоров
...
Рейтинг: 0 / 0
10.04.2014, 09:06
    #38610709
mr_virtus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задачка с несколькими потоками на свой класс семафоров
Blazkowicz,

спасибо за ссылка.

Не могли бы Вы пояснить. Не очень понял смысла:

авторThis implies that every thread accessing a volatile field will read its current value before continuing, instead of (potentially) using a cached value. (However, there is no guarantee about the relative ordering of volatile reads and writes with regular reads and writes, meaning that it's generally not a useful threading construct.)
(In Java 5 or later) Volatile reads and writes establish a happens-before relationship, much like acquiring and releasing a mutex

То есть, если я использую семафор, методы которого не synchronized - программа подвисает.
Например,

Код: java
1.
2.
3.
4.
5.
6.
7.
 public void P()
    { value--;
        if (value < 0)
            try
            {wait();}
            catch (InterruptedException e) {}
    }



Два потока вылетеле после оператора value--;
Будет зависание.

А с volatile как? И что значит закешированное значение?
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Задачка с несколькими потоками на свой класс семафоров / 6 сообщений из 6, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]