Java 什么';在我的例子中,Synchronized和Lock的区别是什么?
我使用Java 什么';在我的例子中,Synchronized和Lock的区别是什么?,java,multithreading,synchronization,locking,Java,Multithreading,Synchronization,Locking,我使用Lock和synchronized编写了一个模拟并发的简单代码 源代码如下: 任务类包括一个名为doSomething()的方法,用于打印线程名称和执行所用时间 import java.util.Calendar; public class Task { public void doSomething() { try { Thread.sleep(2000); } catch (InterruptedException e)
Lock
和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());
}
}
带锁任务类
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);
}
}
Main类
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);
}
}
公共类主{
public static void runableTasks(Class首先,您使用synchronized
的示例构思不周:在对象“a”上同步是一个非常糟糕的主意。请改用以下习惯用法:
private final Object lock = new Object();
public void run() {
synchronized (lock) {
doSomething();
}
}
这会更好,因为通过对外部对象隐藏锁,可以封装同步协议,从而实现更安全的同步策略
现在,synchronized
和java.util.concurrent.locks.Lock
之间的区别在于前者是一个同步原语,而后者是一个更高级的锁定结构,它提供了比synchornized
更精细的操作
您可以查看更多信息,尤其是
synchronized ("A")
这不是同步块的正确用法。在某些情况下,您在进入此同步块时创建了不同的字符串对象,因此每个线程都有不同的锁定对象,因此不同步。正确用法可能如下
synchronized(this)
或
此外,您应该在不同的线程中使用一个可运行的实现,或者将您的锁设置为静态字段私有最终锁
应该是静态的
,或者每个线程都有自己的锁,这使得锁基本上没有用处。在尝试之前,也可以使用.lock()
{
或最后
部分将尝试解锁未锁定的锁(以防.lock()
引发异常)@zapl通过使锁为静态,在任何实例上调用该方法,也会阻止所有其他方法调用,无论它们是否在不同的对象实例上调用。这肯定不是一个有效的锁定策略。@lefty此测试是(据我所见)尝试测试由多个实例共享的锁。如果每个线程都有自己的锁,则根本不需要同步的锁(此处为threads=instances),因为它不封装同步策略,因为其他对象可能“无意”获取锁。
public class TaskWithSync extends Task implements Runnable {
private Object lock = new Object();
@Override
public void run() {
synchronized (lock) {
doSomething();
}
}
}