Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I wrote a simple code to mock concurrency using Lock and synchronized.

Source code is as follows:

Task class includes a method named doSomething() to print the thread name and executing elapsed time.

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 class

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 class

public class TaskWithSync extends Task implements Runnable {

    @Override
    public void run() {
        synchronized ("A") {
            doSomething();
        }
    }
}

Main class

public class Main {
    public static void runableTasks(Class<? extends Runnable> clz)
            throws Exception {
        ExecutorService service = Executors.newCachedThreadPool();

        System.out.printf("<-- Start executing %s Task --> 
",
                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 --> 
", 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);
    }
}

First time, executing tasks with Synchronized by calling method runableTasks(TaskWithSync.class);

<-- 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 --> 

Second time, executing tasks with Lock by calling method runableTasks(TaskWithLock.class);

<-- 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 --> 

With the above example using Lock and synchronized to run the tasks, I have some questions here:

Q1: The timestamp in the synchronized example, it reflects the mutex between 3 Threads. But why is the elapsed time in Lock example the same? I don't know why.

Q2: What's the difference between synchronized and Lock in my example?

Please help me out with these 2 questions.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
179 views
Welcome To Ask or Share your Answers For Others

1 Answer

First of all, your example using synchronized is ill conceived: it is a very bad idea to synchronize on object "A". Use the following idiom instead:

private final Object lock = new Object();

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

This is better because by hiding your lock from external objects, you are encapsulating your synchronization protocol and thereby implementing a safer synchronization policy.

Now, the difference between synchronized and java.util.concurrent.locks.Lock, is that the former is a synchronization primitive whereas the latter a higher level locking construct which provides more elaborate operations than synchornized.

Fore more information you may look at http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html and http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantLock.html in particular.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...