我有三个对象: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;
}
答案 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用于相同的目的,尽管读/写锁是最简单的。