在同一个 class 中执行同步和非同步方法
Execution on synchronized and non-synchronized method in the same class
我在 class 中有两种方法,一种是同步的,另一种是非同步的。当我用两个不同的线程调用这些方法时,我看到执行变成串行而不是并行。
我很困惑,根据理论 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
)。
当第一个线程完成 5 秒的操作时,它开始花费大约 1 秒的时间,同时,第二个线程开始 5 秒的操作。
第一个线程将在第二个线程完成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) None 的其他线程,即 t1 和 t2 可以执行任何其他方法,因为 t2 依赖于同步锁,而 t1 正在等待第一个方法 "doSomething"在开始之前完成 "processSomething".
2) 一旦第一个线程 (t1) "doSomething" 成功执行,两个线程就可以同时执行了。
这里线程将按照上面“@Andy Turner”的评论执行。
我在 class 中有两种方法,一种是同步的,另一种是非同步的。当我用两个不同的线程调用这些方法时,我看到执行变成串行而不是并行。
我很困惑,根据理论 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
)。
当第一个线程完成 5 秒的操作时,它开始花费大约 1 秒的时间,同时,第二个线程开始 5 秒的操作。
第一个线程将在第二个线程完成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) None 的其他线程,即 t1 和 t2 可以执行任何其他方法,因为 t2 依赖于同步锁,而 t1 正在等待第一个方法 "doSomething"在开始之前完成 "processSomething".
2) 一旦第一个线程 (t1) "doSomething" 成功执行,两个线程就可以同时执行了。
这里线程将按照上面“@Andy Turner”的评论执行。