powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Задачка с несколькими потоками на свой класс семафоров
6 сообщений из 6, страница 1 из 1
Задачка с несколькими потоками на свой класс семафоров
    #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
Задачка с несколькими потоками на свой класс семафоров
    #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
Задачка с несколькими потоками на свой класс семафоров
    #38610142
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не используя средства java для синхронизации
Хвастун... интересно что ты будешь использовать взамен.
...
Рейтинг: 0 / 0
Задачка с несколькими потоками на свой класс семафоров
    #38610211
mr_virtus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton,
понял, что погорячился=)
...
Рейтинг: 0 / 0
Задачка с несколькими потоками на свой класс семафоров
    #38610224
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Задачка с несколькими потоками на свой класс семафоров
    #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
6 сообщений из 6, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Задачка с несколькими потоками на свой класс семафоров
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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