Java 8. Проблема синхронизации потоков - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть три объекта: A, B и C. Мне нужна такая синхронизация, чтобы блоки, синхронизированные с объектами A и B, могли выполняться параллельно, и когда выполняется блок, синхронизированный с объектами A, или блок, синхронизированный с объектами B,блок, синхронизированный с объектами C, не может быть выполнен.И когда выполняется блок, синхронизированный с объектами C, блоки, синхронизированные с объектами A и B, не могут быть выполнены.Я пытался использовать объект C в качестве списка, а объекты A и B в качестве объектов, хранящихся в этом списке, но это не сработало.Подскажите пожалуйста, можно ли как-то настроить такую ​​синхронизацию?

import java.util.ArrayList;
import java.util.List;

public class Threads {
    public List<Res> lst = new ArrayList();

    public void startThreads(){
        lst.add(new Res());
        lst.add(new Res());
        Thread t1 = new Thread(new work1());
        Thread t2 = new Thread(new work2());
        Thread t3 = new Thread(new work3());
        t1.start();
        t2.start();
        t3.start();
    }
    public class work1 implements Runnable {
        @Override
        public void run() {
            Method1();
        }
    }
    public class work2 implements Runnable {
        @Override
        public void run() {
             Method2();
        }
    }

    public class work3 implements Runnable {
        @Override
        public void run() {
            Method3();
        }
    }

    public void Method1(){
        synchronized (lst.get(0)/*obj A*/){ 
            //some work
        }
    }

    public void Method2(){
        synchronized (lst.get(1)/*obj B*/){
            //some work
        }
    }

    public void Method3(){
         synchronized (lst)/*obj C*/{
            //some work
        }
    }
}

Class Res:

public class Res {
    public int number = 0;
}

Class Main:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Threads t = new Threads();
        t.startThreads();
    }
}

1 Ответ

1 голос
/ 02 апреля 2019

В вашем случае самое простое (не рекомендуется) решение состоит в том, чтобы защитить Блок A и Блок B различными объектами монитора и защитить Блок C с объектами монитора A и B.

public void Method1(){
    synchronized (A){
        //some work
    }
}

public void Method2(){
    synchronized (B){
        //some work
    }
}

public void Method3(){
    synchronized (A){
        synchronized (B){
            //some work
        }
    }
}

То же самое можно сделать, используя Замки .

public void Method1(){
    lockA.lock();
    try{
        //some work
    } finally {
        lockA.unlock();
    }
}

public void Method2(){
    lockB.lock();
    try{
        //some work
    } finally {
        lockB.unlock();
    }
}

public void Method3(){
    lockA.lock();
    try{
        lockB.lock();
        try{
            //some work
        } finally {
            lockB.unlock();
        }
    } finally {
        lockA.unlock();
    }
}

Или вы можете использовать блокировку чтения / записи, как предложено shmosel в комментариях.

public void Method1(){
    readWriteLock.readLock().lock();
    try{
        //some work
    } finally {
        readWriteLock.readLock().unlock();
    }
}

public void Method2(){
    readWriteLock.readLock().lock();
    try{
        //some work
    } finally {
        readWriteLock.readLock().unlock();
    }
}

public void Method3(){
    readWriteLock.writeLock().lock();
    try{
        //some work
    } finally {
        readWriteLock.writeLock().unlock();
    }
}

Вы также можете использовать CountDownLatch для той же цели, хотя блокировка чтения / записи является самой простой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...