1.Lock接口
java.utils.concurrent包是jdk1.5新增的,用来处理多线程。实现java.util.concurrent.locks.Lock接口的类具有与synchronized关键字同样的功能,但是它更加强大一些。java.utils.concurrent.locks.ReentrantLock是较常用的实现了Lock接口的类。下面是ReentrantLock类的一个应用实例:
lock()方法用于锁定对象,unlock()方法用于释放对对象的锁定,他们都是在Lock接口中定义的方法。位于这两个方法之间的代码在被执行时,效果等同于被放在synchronized同步块中。
一般用法是将需要在lock()和unlock()方法之间执行的代码放在try{}块中,并且在finally{}块中调用unlock()方法,这样就可以保证即使在执行代码抛出异常的情况下,对象的锁也总是会被释放,否则的话就会为死锁的产生增加可能。
和synchronized关键字不同,lock只把当前方法锁定,其他的方法(不论是同步还是非同步的)并没有被锁定。
2.死锁
死锁就是一个进程中的每个线程都在等待这个进程中的其他线程释放所占用的资源,从而导致所有线程都无法继续执行的情况。死锁是多线程编程中一个隐藏的陷阱,它经常发生在多个线程共用资源的时候。在实际开发中,死锁一般隐藏的较深,不容易被发现。程序中必须同时满足以下四个条件才会引发死锁:
(1)互斥(Mutual exclusion):线程所使用的资源中至少有一个是不能共享的,它在同一时刻只能由一个线程使用。
(2)持有与等待(Hold and wait):至少有一个线程已经持有了资源,并且正在等待获取其他的线程所持有的资源。
(3)非抢占式(No pre-emption):如果一个线程已经持有了某个资源,那么在这个线程释放这个资源之前,别的线程不能把它抢夺过去使用。
(4)循环等待(Circular wait):假设有N个线程在运行,第一个线程持有了一个资源,并且正在等待获取第二个线程持有的资源,而第二个线程正在等待获取第三个线程持有的资源,依此类推……第N个线程正在等待获取第一个线程持有的资源,由此形成一个循环等待。
java.utils.concurrent包是jdk1.5新增的,用来处理多线程。实现java.util.concurrent.locks.Lock接口的类具有与synchronized关键字同样的功能,但是它更加强大一些。java.utils.concurrent.locks.ReentrantLock是较常用的实现了Lock接口的类。下面是ReentrantLock类的一个应用实例:
- package edu.hust.test;
- import java.util.concurrent.locks.ReentrantLock;
- public class ThreadLock extends ReentrantLock {
- private static final long serialVersionUID = 1L;
- public void execute_lock1() {
- this.lock();
- try {
- for (int i = 0; i < 5; i++) {
- System.out.println(Thread.currentThread().getName() + " 位于/"同步块/"中 " + i);
- Thread.sleep(999999999);
- }
- } catch (InterruptedException e) {
- System.out.println("谁把我吵醒了.....");
- } finally {
- this.unlock();
- }
- }
- public synchronized void execute_lock2() {
- //lock.lock();
- try {
- for (int i = 0; i < 5; i++)
- System.out.println(Thread.currentThread().getName() + " 位于/"同步块/"中 " + i);
- } finally {
- //lock.unlock();
- }
- }
- public static void main(String[] args) {
- final ThreadLock threadLock = new ThreadLock();
- Thread thread1 = new Thread(new Runnable() {
- public void run() {
- threadLock.execute_lock1();
- }
- }, "红薯Thread");
- Thread thread2 = new Thread(new Runnable() {
- public void run() {
- threadLock.execute_lock1();
- }
- }, "土豆Thread");
- Thread thread3 = new Thread(new Runnable() {
- public void run() {
- threadLock.execute_lock2();
- }
- }, "青菜Thread");
- thread1.start();
- thread2.start();
- thread3.start();
- }
- /*
- * 输出结果:
- * 红薯Thread 位于"同步块"中 0
- * 青菜Thread 位于"同步块"中 0
- * 青菜Thread 位于"同步块"中 1
- * 青菜Thread 位于"同步块"中 2
- * 青菜Thread 位于"同步块"中 3
- * 青菜Thread 位于"同步块"中 4
- * */
- }
和synchronized关键字不同,lock只把当前方法锁定,其他的方法(不论是同步还是非同步的)并没有被锁定。
2.死锁
死锁就是一个进程中的每个线程都在等待这个进程中的其他线程释放所占用的资源,从而导致所有线程都无法继续执行的情况。死锁是多线程编程中一个隐藏的陷阱,它经常发生在多个线程共用资源的时候。在实际开发中,死锁一般隐藏的较深,不容易被发现。程序中必须同时满足以下四个条件才会引发死锁:
(1)互斥(Mutual exclusion):线程所使用的资源中至少有一个是不能共享的,它在同一时刻只能由一个线程使用。
(2)持有与等待(Hold and wait):至少有一个线程已经持有了资源,并且正在等待获取其他的线程所持有的资源。
(3)非抢占式(No pre-emption):如果一个线程已经持有了某个资源,那么在这个线程释放这个资源之前,别的线程不能把它抢夺过去使用。
(4)循环等待(Circular wait):假设有N个线程在运行,第一个线程持有了一个资源,并且正在等待获取第二个线程持有的资源,而第二个线程正在等待获取第三个线程持有的资源,依此类推……第N个线程正在等待获取第一个线程持有的资源,由此形成一个循环等待。
- package edu.hust.test;
- /**
- * @author Forrest He
- * created on 2008-11-17
- */
- public class DeadLockDemo implements Runnable {
- int i; //用于判断线程是否被占用
- /*
- * 必须是static的, static表示锁住的是Object类; 而非static锁住的是Object的对象, 在这里不符合要求.
- * */
- private static Object print_one = new Object(); //第一台打印机
- private static Object print_two = new Object(); //第二台打印机
- public void run() {
- if (i == 0) { //先占用print_one, 并等待print_two
- synchronized (print_one) {
- System.out.println("print_one已被占用, 正等待print_two");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- System.err.println("谁把我吵醒了!!!");
- }
- synchronized (print_two) {
- System.out.println("已获取print_two, 任务完成");
- }
- }
- } else if (i == 1) { //先占用print_two, 并等待print_one
- synchronized (print_two) {
- System.out.println("print_two已被占用, 正等待print_one");
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- System.err.println("谁把我吵醒了!!!");
- }
- synchronized (print_one) {
- System.out.println("已获取print_one, 任务完成");
- }
- }
- }
- }
- public static void main(String[] args) {
- DeadLockDemo deadLock_one = new DeadLockDemo();
- DeadLockDemo deadLock_two = new DeadLockDemo();
- deadLock_one.i = 0;
- deadLock_two.i = 1;
- new Thread(deadLock_one).start();
- new Thread(deadLock_two).start();
- }
- }