我想很多购买了《Java程序员面试宝典》
问:请对比synchronized与java.util.
答案:主要相同点:
主要不同点:
恩,让我们先鄙视一下应试教育。
言归正传,我们先来看一个多线程程序。
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->public class ThreadDemo implements Runnable {
class Student {
private int age = 0;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Student student = new Student();
int count = 0;
public static void main(String[] args) {
ThreadDemo td = new ThreadDemo();
Thread t1 = new Thread(td, "a");
Thread t2 = new Thread(td, "b");
Thread t3 = new Thread(td, "c");
t1.start();
t2.start();
t3.start();
}
public void run() {
accessStudent();
}
public void accessStudent() {
String currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " is running!");
synchronized (this) {//(1)使用同一个ThreadDemo对象作为同步锁
System.out.println(currentThreadName + " got lock1@Step1!");
try {
count++;
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(currentThreadName + " first Reading count:" + count);
}
}
System.out.println(currentThreadName + " release lock1@Step1!");
synchronized (this) {//(2)使用同一个ThreadDemo对象作为同步锁
System.out.println(currentThreadName + " got lock2@Step2!");
try {
Random random = new Random();
int age = random.nextInt(100);
System.out.println("thread " + currentThreadName + " set age to:" + age);
this.student.setAge(age);
System.out.println("thread " + currentThreadName + " first read age is:" + this.student.getAge());
Thread.sleep(5000);
} catch (Exception ex) {
ex.printStackTrace();
} finally{
System.out.println("thread " + currentThreadName + " second read age is:" + this.student.getAge());
}
}
System.out.println(currentThreadName + " release lock2@Step2!");
}
}
运行结果:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->a is running!
a got lock1@Step1!
b is running!
c is running!
a first Reading count:1
a release lock1@Step1!
a got lock2@Step2!
thread a set age to:76
thread a first read age is:76
thread a second read age is:76
a release lock2@Step2!
c got lock1@Step1!
c first Reading count:2
c release lock1@Step1!
c got lock2@Step2!
thread c set age to:35
thread c first read age is:35
thread c second read age is:35
c release lock2@Step2!
b got lock1@Step1!
b first Reading count:3
b release lock1@Step1!
b got lock2@Step2!
thread b set age to:91
thread b first read age is:91
thread b second read age is:91
b release lock2@Step2!
成功生成(总时间:30 秒)
显然,在这个程序中,
转载注明出处:http://x- spirit.javaeye.com/、http: //www.blogjava.net/zhangwei217245/
我想一定有人会说:
那么好。我们把第二个同步块中的对象锁改为student(
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->a is running!
a got lock1@Step1!
b is running!
c is running!
a first Reading count:1
a release lock1@Step1!
a got lock2@Step2!
thread a set age to:73
thread a first read age is:73
c got lock1@Step1!
thread a second read age is:73
a release lock2@Step2!
c first Reading count:2
c release lock1@Step1!
c got lock2@Step2!
thread c set age to:15
thread c first read age is:15
b got lock1@Step1!
thread c second read age is:15
c release lock2@Step2!
b first Reading count:3
b release lock1@Step1!
b got lock2@Step2!
thread b set age to:19
thread b first read age is:19
thread b second read age is:19
b release lock2@Step2!
成功生成(总时间:21 秒)
从修改后的运行结果来看,显然,由于同步块的对象锁不同了,
转载注明出处:http://x- spirit.javaeye.com/、http: //www.blogjava.net/zhangwei217245/
可见,使用不同的对象锁,在不同的同步块中完成任务,
很多人看到这不禁要问:这和新的Lock框架有什么关系?
别着急。我们这就来看一看。
synchronized块的确不错,
1. 它无法中断一个正在等候获得锁的线程,
2.
转载注明出处:http://x- spirit.javaeye.com/、http: //www.blogjava.net/zhangwei217245/
java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。这就为 Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、
JDK 官方文档中提到:
ReentrantLock是“一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,
ReentrantLock 将由最近成功获得锁,并且还没有释放该锁的线程所拥有。
简单来说,
转载注明出处:http://x- spirit.javaeye.com/、http: //www.blogjava.net/zhangwei217245/
ReentrantLock 类(重入锁)实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票、
我们把上面的例程改造一下:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
-->public class ThreadDemo implements Runnable {
class Student {
private int age = 0;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Student student = new Student();
int count = 0;
ReentrantLock lock1 = new ReentrantLock(false);
ReentrantLock lock2 = new ReentrantLock(false);
public static void main(String[] args) {
ThreadDemo td = new ThreadDemo();
for (int i = 1; i <= 3; i++) {
Thread t = new Thread(td, i + "");
t.start();
}
}
public void run() {
accessStudent();
}
public void accessStudent() {
String currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " is running!");
lock1.lock();//使用重入锁
System.out.println(currentThreadName + " got lock1@Step1!");
try {
count++;
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(currentThreadName + " first Reading count:" + count);
lock1.unlock();
System.out.println(currentThreadName + " release lock1@Step1!");
}
lock2.lock();//使用另外一个不同的重入锁
System.out.println(currentThreadName + " got lock2@Step2!");
try {
Random random = new Random();
int age = random.nextInt(100);
System.out.println("thread " + currentThreadName + " set age to:" + age);
this.student.setAge(age);
System.out.println("thread " + currentThreadName + " first read age is:" + this.student.getAge());
Thread.sleep(5000);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
System.out.println("thread " + currentThreadName + " second read age is:" + this.student.getAge());
lock2.unlock();
System.out.println(currentThreadName + " release lock2@Step2!");
}
}
}
从上面这个程序我们看到:
对象锁的获得和释放是由手工编码完成的,
这说明两点问题:
1. 新的ReentrantLock的确实现了和同步块相同的语义功
2. 使用新的ReentrantLock,
3. 使用新的ReentrantLock,
转载注明出处:http://x- spirit.javaeye.com/、http: //www.blogjava.net/zhangwei217245/
细心的读者又发现了:
在我们的例程中,创建ReentrantLock实例的时候,
转载注明出处:http://x- spirit.javaeye.com/、http: //www.blogjava.net/zhangwei217245/
转载注明出处:http://x- spirit.javaeye.com/、http: //www.blogjava.net/zhangwei217245/