Java Multithreading: Lock Objects
This is the fourth part of our advanced Java multi-threading
tutorial. In this tutorial I show you how you can use multiple locks to speed
up complex multi-threaded code, sometimes dramatically.
Code For This Tutorial
App.java:
import
java.util.ArrayList;
import java.util.List;
import
java.util.Random;
public class App {
public static void main(String[]
args) {
Worker worker = new Worker();
worker.main();
}
}
Using
Synchonized Methods
class Worker {
private Random random = new Random();
private
List<Integer> list1 = new ArrayList<Integer>();
private
List<Integer> list2 = new ArrayList<Integer>();
public synchronized void stageOne() {
try {
Thread.sleep(1);
} catch
(InterruptedException e) {
// TODO
Auto-generated catch block
e.printStackTrace();
}
list1.add(random.nextInt(100));
}
public synchronized void stageTwo() {
try {
Thread.sleep(1);
} catch
(InterruptedException e) {
// TODO
Auto-generated catch block
e.printStackTrace();
}
list2.add(random.nextInt(100));
}
public void process() {
for (int i = 0; i <
1000; i++) {
stageOne();
stageTwo();
}
}
public void main() {
System.out.println("Starting
...");
long start = System.currentTimeMillis();
Thread t1 = new Thread(new Runnable() {
public void run() {
process();
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
process();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch
(InterruptedException e) {
// TODO
Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Time
taken: " + (end - start));
System.out.println("List1:
" + list1.size() + "; List2: "
+ list2.size());
}
}
Output:
Starting ...
Time taken: 4413
List1: 2000;
List2: 2000
Time taken to
execute thread is Approx 4secs because while running one synchronized method it
will not allow to run other methods due to lock on object.
class Worker {
private Random random = new Random();
private Object lock1 = new Object();
private Object lock2 = new Object();
private
List<Integer> list1 = new ArrayList<Integer>();
private
List<Integer> list2 = new ArrayList<Integer>();
public void stageOne() {
synchronized (lock1) {
try {
Thread.sleep(1);
} catch
(InterruptedException e) {
// TODO
Auto-generated catch block
e.printStackTrace();
}
list1.add(random.nextInt(100));
}
}
public void stageTwo() {
synchronized (lock2) {
try {
Thread.sleep(1);
} catch
(InterruptedException e) {
// TODO
Auto-generated catch block
e.printStackTrace();
}
list2.add(random.nextInt(100));
}
}
public void process() {
for(int i=0; i<1000;
i++) {
stageOne();
stageTwo();
}
}
public void main() {
System.out.println("Starting
...");
long start = System.currentTimeMillis();
Thread t1 = new Thread(new Runnable() {
public void run() {
process();
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
process();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch
(InterruptedException e) {
// TODO
Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Time
taken: " + (end - start));
System.out.println("List1:
" + list1.size() + "; List2: " + list2.size());
}
}
Output:
Starting ...
Time taken: 2022
List1: 2000; List2: 2000
Time taken to execute threads is Approx 2secs because here two
threads run parallel, load will on CPU. Synchronized block will not acquire
lock on object.
No comments:
Post a Comment