在同一个类中执行同步和非同步方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在同一个类中执行同步和非同步方法相关的知识,希望对你有一定的参考价值。

我在一个类中有两个方法,一个是同步的,另一个是非同步的。当我用两个不同的线程调用这些方法时,我看到执行变得串行不并行。

我很困惑,根据理论,r.processSomething()不应该等待r.doSomething()来完成它的执行。

如果有人对同时执行两种方法(同步和非同步)有所了解。请分享。

class LockObjectDemo{

    public static void main(String[] args){

        SharedResource r = new SharedResource();

        MyThread t1 = new MyThread(r);
        t1.start();

        MyThread t2 = new MyThread(r);
        t2.start();

    }
}


class MyThread extends Thread{
    private SharedResource r ;

    MyThread(SharedResource r){
        this.r = r;
    }

    public void run() {     
        try {
            r.doSomething(); // Only after completing this method , the other thread enters into the next method which is not locked
            r.processSomething();           
        } catch(Exception ex){
            System.out.println(ex);
        }

    }
}

class SharedResource{

    public void doSomething() throws Exception{
        synchronized(this){ 
            System.out.println("Doing Something -> "+Thread.currentThread().getName());
            Thread.sleep(5000);
            System.out.println("Done Something->"+Thread.currentThread().getName());
        }
    }

    public void processSomething() throws Exception{
        System.out.println("Processing Something -> "+Thread.currentThread().getName());
        Thread.sleep(1000);
        System.out.println("Done Processing->"+Thread.currentThread().getName());
    }
}
答案

你有2件事,花了〜5s,连续执行(因为synchronized)。

当第一个线程完成5s动作时,它会以~1s开始,同时第二个线程开始5s动作。

第一个线程将在第二个线程完成5s操作之前完成1s操作。然后第二个线程执行1s操作。

因此,1s操作不会同时执行。

图形:

Thread 1:  |<----- 5s ----->|<- 1s ->|
Thread 2:                   |<----- 5s ----->|<- 1s ->|
另一答案

对“@Andy Turner”分享的上述解决方案的进一步分析。

在这个问题中,我们必须考虑以下两件事。

1)MyThread-t1和t2共享相同的SharedResource r。这将限制“doSomething”的执行,因此执行将以串行方式发生。根据首先选择的线程,另一个线程必须等到第一个线程执行成功完成。即睡5秒。

对于这个问题,我们假设

a)线程t1首先开始运行,即t1.doSomething()

b)其他线程,即t1和t2都不能执行任何其他方法,因为t2依赖于同步锁定而t1正在等待第一个方法“doSomething”在它可以启动“processSomething”之前完成。

2)成功执行第一个线程(t1)“doSomething”后,线程都处于同时执行的位置。

这里的线程将由上面的“@Andy Turner”评论执行。

以上是关于在同一个类中执行同步和非同步方法的主要内容,如果未能解决你的问题,请参考以下文章

多线程 Thread 线程同步 synchronized

初学Java多线程:使用Synchronized块同步方法

同步异步阻塞和非阻塞

108 同步异步阻塞和非阻塞

第十九节——线程与同步代码块和锁

同步互斥阻塞