我写了一个简单的代码来模拟使用Lock
and的并发synchronized
。
源代码如下:
任务类 包括一个doSomething()
用于打印线程名称和执行经过时间的方法。
import java.util.Calendar;
public class Task {
public void doSomething() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
StringBuilder sb = new StringBuilder();
//Thread Name
sb.append("Thread Name: ").append(Thread.currentThread().getName());
//Timestamp for the executing
sb.append(", elaspsed time: ").append(Calendar.getInstance().get(13)).append(" s ");
System.out.println(sb.toString());
}
}
TaskWithLock 类
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TaskWithLock extends Task implements Runnable {
private final Lock lock = new ReentrantLock();
@Override
public void run() {
try {
lock.lock();
doSomething();
} finally {
lock.unlock();
}
}
}
TaskWithSync 类
public class TaskWithSync extends Task implements Runnable {
@Override
public void run() {
synchronized ("A") {
doSomething();
}
}
}
主 班
public class Main {
public static void runableTasks(Class<? extends Runnable> clz)
throws Exception {
ExecutorService service = Executors.newCachedThreadPool();
System.out.printf("<-- Start executing %s Task --> \n",
clz.getSimpleName());
// Start 3 threads
for (int i = 0; i < 3; i++) {
service.submit(clz.newInstance());
}
// Wait for some time, and then close the executor
TimeUnit.SECONDS.sleep(10);
System.out
.printf("<-- %s Tasks is complet --> \n", clz.getSimpleName());
service.shutdown();
}
public static void main(String[] args) throws Exception {
//Execute tasks with Lock
runableTasks(TaskWithLock.class);
//Execute tasks with Synchronized
//runableTasks(TaskWithSync.class);
}
}
第一次,通过调用方法 runableTasks(TaskWithSync.class); 执行带有Synchronized的任务 ;
<-- Start executing TaskWithSync Task -->
Thread Name: pool-1-thread-1, elaspsed time: 28 s
Thread Name: pool-1-thread-3, elaspsed time: 30 s
Thread Name: pool-1-thread-2, elaspsed time: 32 s
<-- TaskWithSync Tasks is complet -->
第二次,通过调用 runableTasks(TaskWithLock.class) 方法使用Lock执行任务 ;
<-- Start executing TaskWithLock Task -->
Thread Name: pool-1-thread-3, elaspsed time: 23 s
Thread Name: pool-1-thread-2, elaspsed time: 23 s
Thread Name: pool-1-thread-1, elaspsed time: 23 s
<-- TaskWithLock Tasks is complet -->
在使用Lock
和synchronized
运行任务的上述示例中,我在这里有一些问题:
Q1: 同步示例中的时间戳,它反映了3个线程之间的互斥量。但是,为什么Lock示例中的经过时间相同?我不知道为什么
Q2:synchronized
和Lock
我的示例之间有什么区别?
请帮助我解决这两个问题。
首先,您使用的示例synchronized
不正确:在对象“ A”上同步是一个非常糟糕的主意。请改用以下成语:
private final Object lock = new Object();
public void run() {
synchronized (lock) {
doSomething();
}
}
这样比较好,因为通过从外部对象隐藏锁,可以封装同步协议,从而实现更安全的同步策略。
现在,之间的差值synchronized
和java.util.concurrent.locks.Lock
,在于前者是原语而后者更高的水平锁定构建体,其提供了比更复杂的操作的同步synchornized
。
有关更多信息,请参见http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html和
http://docs.oracle.com/javase/7尤其是/docs/api/java/util/concurrent/locks/ReentrantLock.html。
问题内容: 这两个关键字具有完全相同的效果,还是我应该注意一些事情? 问题答案: 根据此站点的资料:[http]( http://en.csharp- online.net/CSharp_FAQ:_What_is_the_difference_between_CSharp_lock_and_Java_synchronized) //en.csharp-online.net/CSharp_FAQ :
问题内容: 对于旅行预订Web应用程序,如果有100个并发用户登录,是否应该通过“同步”或“静态同步”方法来实现机票预订并生成“电子机票编号”? 问题答案: 好了,您是否知道静态方法和实例方法之间的一般区别? 唯一的区别是,在VM开始运行该方法之前,它必须获取监视器。对于实例方法,获得的锁是与您要在其上调用该方法的对象相关联的锁。对于静态方法,获取的锁与类型本身关联- 因此,其他线程将无法同时调用
问题内容: Java中的同步方法和同步块有什么区别? 我一直在网上搜索答案,人们似乎对此不太确定:-( 我的看法是,两者之间没有区别,只是synch块的作用域可能更多,因此锁定的时间更少了? 如果在静态方法上使用Lock,则采用什么Lock?班级锁是什么意思? 问题答案: 同步方法将方法接收器用作锁(即,用于非静态方法,而用于静态方法的封闭类)。 blocks将表达式用作锁。 因此,以下两种方法等
问题内容: 可以说我们有以下两个示例代码: 还有这个 所以有人可以告诉我现在有什么区别吗? 问题答案: 这两种不同的方法在 功能上是等效的 。有 可能 是一个非常小的 性能 差异: 在字节码级别,作为方法访问标记中设置的位, 同步方法 公布其同步需求。JVM查找该位标志并进行适当同步。 该 同步块 通过存储在该方法的类文件中的字节码定义的操作序列实现其同步。 因此,同步方法 可能会以 更快的速度执
问题内容: 之间有什么区别 和 如果我错了,请忽略此问题。 问题答案: 在第一个线程中,只有一个线程一次可以执行整个方法,而在第二个线程中,如果不将 其 用作参数,则只有一个线程可以执行该同步块。 这是它的副本。使用同步方法而不是同步块是否有优势?
问题内容: 我知道同步方法和同步块之间的区别,但是我不确定同步块部分。 假设我有这段代码 在这种情况下,使用 lockObject 和将 其 用作锁之间有什么区别?对我来说似乎是一样的。 当您决定使用同步块时,如何确定哪个对象是锁? 问题答案: 我个人几乎从不锁定“ this”。我通常锁定一个私有的引用,我知道没有其他代码可以锁定。如果您锁定“ this”,那么 任何 其他了解您对象的代码都可能选