Java 8.线程同步问题

时间:2019-04-02 20:28:35

标签: java multithreading synchronization

我有三个对象:A,B和C。 我需要这样的同步,以便可以并行执行与对象A和B同步的块,并且当执行与对象A同步的块或与对象B同步的块时,不能执行与对象C同步的块。并且当执行与对象C同步的块时,无法执行与对象A和B同步的块。我试图将对象C用作列表,将对象A和B用作存储在此列表中的对象,但是它不起作用。请告诉我,是否可以通过某种方式配置这种同步?

public class Program
{
    public static async Task Main(string[] args)
    {
        using (var cancelSource = new CancellationTokenSource())
        {
            try
            {
                await new HostBuilder()
                    .ConfigureServices((hostContext, services) =>
                    {
                        services.AddHostedService<TestService>();
                    })
                    .Build()
                    .RunAsync(cancelSource.Token);
            }
            catch (Exception E)
            {
                cancelSource.Cancel();
            }
        }
    }
}
public class TestService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {

        while (!stoppingToken.IsCancellationRequested)
        {
            await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
            Console.WriteLine("loop 1");
            throw new ApplicationException("OOPS!!");
        }
    }
}

Class Res:

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
        }
    }
}

主要班级:

public class Res {
    public int number = 0;
}

1 个答案:

答案 0 :(得分:1)

在您的情况下,最简单(不推荐)的解决方案是用不同的监视器对象保护Block A和Block B,并用A和B的监视器对象保护Block C。

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

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

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

同样可以使用Locks完成。

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用于相同的目的,尽管读/写锁是最简单的。