都不想有错误,但一不小心就犯了

-------------------15/4/17  by codeZhu --------------  java.lang.IllegalMonitorStateException-------------------------------------------------

  下午写ReentrantLock的中断,本以为可以顺利的写出来,结果希望越大失望越大,写完一运行,给我哗啦的来了个java.lang.IllegalMonitorStateException,这个错误以前

也见过,相信大家都还记得是在wait()与notify()中。对于这个错误有句话说的很好  “当前的线程不是此对象监视器的所有者”。通俗一点就是不是你的你还拿过来瞎用,程序和人一样

也有脾气,想想你自己是不是也不喜欢别人瞎用你的东西,瞎用了你会发脾气,程序就会报错,这个错误就是IllegalMonitorStateException。

  既然有了错误就来找找是在哪里啦。但感觉今天诸事不顺,就是没找到,我把错误的代码贴出来看看。

 1 public class ReenTrantLockTest {
 2     //reentrantLock锁
 3     ReentrantLock lock = new ReentrantLock();
 4     public static void main(String[] args) {
 5         ReenTrantLockTest test = new ReenTrantLockTest();
 6         //启动线程1执行任务
 7         test.new MyThread1().start();
 8         //再启动线程2去执行,此时线程2会一直等待锁
 9         final Thread thread2 = test.new MyThread2();
10         thread2.start();
11         //等待一会,然后尝试去中断线程2
12         long start = System.currentTimeMillis();
13         while(true) {
14             if (System.currentTimeMillis()
15                     - start > 5000) {
16                 System.out.println("不等了,尝试中断");
17                 thread2.interrupt();  //此处中断读操作
18                 break;
19             }
20         }
21     }
22     //两个内部线程
23     class MyThread1 extends Thread{
24         //线程1处理一些事情,并加上锁
25         public void run() {
26             try{
27             lock.lock();
28             System.out.println("开始执行");
29             //用循环制造一点延时,代表执行的过程没完没了
30             while(true){
31                 int i = 0;
32                 if(i>Integer.MAX_VALUE){
33                     break;
34                 }
35             }
36             System.out.println("执行完毕");
37             }finally{
38                 lock.unlock();
39             }
40         }
41     }
42     
43     class MyThread2 extends Thread{
44         //线程2也处理一些事情,并加上不可中断锁
45         @Override
46         public void run() {
47             try{
48                 lock.lockInterruptibly();
49                 System.out.println(Thread.currentThread().getName());
50             } 
51             catch (InterruptedException e) {
52                 System.out.println("不等了");
53             }
54             finally{
55                 lock.unlock();
56             }
57             System.out.println("中断成功,去执行其他任务");
58         }
59     }
60 }

  经过仔细的观察,还是让我看到了那个错误的原因,真是苍天不负苦心人啊。错误原因是什么呢?下面就来说说,在我们写 lock.lockInterruptibly()的时候,是需要主动

释放锁的,并且以防万一,要将  lock.unlock()写在 finally中,线程执行的部分(文中就是System.out.println(Thread.currentThread().getName()))要写在 try中,

马虎一看上面的也是按照这么来的,但是问题就在这个最后的finally{ lock.unlock();}上了,按照上面的写法,不管怎样最后都是要执行finally的,也就是要释放锁,但此时

这个线程就是因为苦苦等待锁才要中断的,而你一释放锁是不是就满足了上面的那句话  “当前的线程不是此对象监视器的所有者”,不是你的你还瞎搞,能不报错才怪,于是赶紧的

改过来。

 1     class MyThread2 extends Thread{
 2         //线程2也处理一些事情,并加上不可中断锁
 3         @Override
 4         public void run() {
 5             try{
 6                 lock.lockInterruptibly();
           //在这里用try...finally就不会释放锁了
7 try{ 8 System.out.println(Thread.currentThread().getName()); 9 }finally{ 10 lock.unlock(); 11 } 12 } 13 catch (InterruptedException e) { 14 System.out.println("不等了"); 15 } 16 17 System.out.println("终端成功,去执行其他任务"); 18 } 19 }

 

既然都写到这里了是不是该把wait()与notify()中的错误也看一看,不过要先吃饭了。。

  再看如下的代码,看看错误的原因还是一样,我拿着自己的 锁想打开别人的房子,这是怎么可能的,比人是不是要报警抓你啦!,因此我们只需要将synchronized(thread1)

中的thread1改为test就可以了。

 1 public class NotifyTest {
 2     
 3     static NotifyTest test = new NotifyTest();
 4     public static void main(String[] args) throws Exception {
 5         
 6         Thread thread1 = test.new Mythread1();
 7         thread1.start();
 8         Thread.currentThread().sleep(1000);
 9         synchronized(thread1){
10             System.out.println("开始叫醒");
11             test.notify();
12             System.out.println("叫醒结束");
13         }
14     }
15     
16     class Mythread1 extends Thread{
17         public void run() {
18             synchronized(test){
19                 System.out.println(Thread.currentThread().getName());
20                 try {
21                     System.out.println("开始等待");
22                     test.wait(Integer.MAX_VALUE);
23                     System.out.println("结束等待");
24                 } catch (InterruptedException e) {
25                     e.printStackTrace();
26                 }
27             }
28         }
29     }
30 }

  好啦,这个异常相信以后再遇到就知道怎么修改了...NO,NO 不是的,应该是以后再也不遇到了...不过我倒是有点喜欢碰到异常了,人非圣贤,孰能无错,碰到错误再解决错误

才是让人最高兴的。

---------------------------------------------------------------------------------------------------------------------------------------------------------

 

posted @ 2015-04-17 17:50  codeZhu  阅读(246)  评论(0编辑  收藏  举报