当前位置: 首页 > 面试题库 >

在我的示例中,同步和锁定有什么区别?

裴硕
2023-03-14
问题内容

我写了一个简单的代码来模拟使用Lockand的并发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 -->

在使用Locksynchronized运行任务的上述示例中,我在这里有一些问题:

Q1: 同步示例中的时间戳,它反映了3个线程之间的互斥量。但是,为什么Lock示例中的经过时间相同?我不知道为什么

Q2:synchronizedLock我的示例之间有什么区别?

请帮助我解决这两个问题。


问题答案:

首先,您使用的示例synchronized不正确:在对象“ A”上同步是一个非常糟糕的主意。请改用以下成语:

private final Object lock = new Object();

public void run() {
    synchronized (lock) {
        doSomething();
    }
}

这样比较好,因为通过从外部对象隐藏锁,可以封装同步协议,从而实现更安全的同步策略。

现在,之间的差值synchronizedjava.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”,那么 任何 其他了解您对象的代码都可能选