A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 付玉光 于 2013-3-8 15:49 编辑

师哥师姐们,在帮小兄我一个大帮呀,自我感觉多线程这块真费解!


①wait(),notify(),notifyAll()都是操作线程的方法,为什么不定义在Thread类中,而定义在Object中呢?

②interrupt(),interrupted(),isInterrupted()这三个方法有什么区别和联系呀?仅仅一个静态的interrupted()方法就让我很挠头了!{:soso_e100:}


4 个回复

倒序浏览

回帖奖励 +6

本帖最后由 Pf_D 于 2013-2-26 14:13 编辑

多线程非一日之功,其所涉及的是一门学科,即Parallel Computatio。Jeffrey在其书《Windows Internal》中曾说他自上世纪九十年代开始写多线程程序,直到完成这本书时尚不能说自己写多线程程序可以确保无误。
每个函数的作用无法具体说明,文档中对此也是模模糊糊(楼主可以去看java.lang中的thread一节)

问题1
小生接触Java的时间较短,暂时无法替楼主解决。

问题2
void interrupt()
          Interrupts this thread.
static boolean interrupted()
          Tests whether the current thread has been interrupted
boolean isInterrupted()
          Tests whether this thread has been interrupted.
以上的this均指的是主调线程!
回复 使用道具 举报
1.  某线程必须获取欲调用实例的锁定,才能调用 wait 方法 notify方法,notifyAll方法。
   wait notify notifyAll都是java.lang的Object类的方法,不是Thread类固有的方法。
2.(1)interrupt:置线程的中断状态
  (2)isInterrupt:线程是否中断
  (3)interrupted:返回线程的上次的中断状态,并清除中断状态
       例如: 在 while(!Thread.currentThread().isInterrupted()) {  
                          当达到队列容量时,在这里会阻塞   
                  put的内部会调用LockSupport.park()这个是用来阻塞线程的方法   
                  当其他线程,调用此线程的interrupt()方法时,会设置一个中断标志   
                 LockSupport.part()中检测到这个中断标志,会抛出InterruptedException,并清除线程的中断标志
                 由于阻塞库函数,如:Object.wait,Thread.sleep除了抛出异常外,还会清除线程中断状态,因此可能在这里要保留线程的中断状态   
                 因此在异常段调用Thread.currentThread().isInterrupted()返回为false   
             另外,Thread.interrupted()在jdk库的源代码中比较常用,因为它既可以得到上一次线程的中断标志值,又可以同时清除线程的中断标志
                  若在得到一个异常的同时,线程的中断状态已经被清除了,需要保留线程的中断状态,则需要调用Thread.currentThread().interrupt()

评分

参与人数 1黑马币 +6 收起 理由
张庚 + 6 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 付玉光 于 2013-3-7 16:29 编辑

{:soso_e101:}有时,真郁闷,自己提的问题,自己回答,

关于第一个问题:

        这些方法都只能存在于同步代码块中,而使用这些方法时必须要标识所属的同步锁,
        而同步锁上监视器可以是任意对象,所以任意对象调用的方法一定要定义在object类中,
        才符合逻辑呀。


②第二个问题



//从该例中可证明,当前线程调用interrupt()方法并不能使,线程停止。

class MyClass1 extends Thread{
        public void run(){
                        for(int i=1;i<5;i++){
                                if(i>2)
                                        interrupt();
                                System.out.println(Thread.currentThread().getName()+" "+i);
                        }
        }

        public static void main(String[] args){
                        MyClass1 my=new MyClass1();
                        my.start();
        }
}

//该例证明:interrupted方法作用:是测试当前线程是否已经中断,线程的中断状态 由该方法清除。

class MyClass2 extends Thread{
        public void run(){
                try{
                                        for(int i=1;i<5;i++){
                                                System.out.print(i+" ");

                                                if(i>2)
                                                        interrupt();

                                                //该句作用:清除中断状态,使程序继续运行。
                                                interrupted();

                                                sleep(1000);
                                                        
                                        }
                }catch(InterruptedException e){
                        System.out.println("caught");
                }
        }

        public static void main(String[] args){
                        MyClass2 my=new MyClass2();
                        my.start();
        }
}

//isInterrupt方法的作用是:测试线程是否已经中断,如果已经中断,则返回 true;否则返回 false。

class MyClass3 extends Thread{

        public void run(){
                        int i=0;
                try{
                                        //如果中断,则退出循环。
                                        while(!isInterrupted()){
                                                ++i;
                                                System.out.println(Thread.currentThread().getName()+" "+i);
                                                if(i>4)
                                                        interrupt();
                                                sleep(1000);
                                                        
                                        }
                }catch(InterruptedException e){
                        System.out.println("结束");
                }
        }

        public static void main(String[] args){
                        MyClass3 my=new MyClass3();
                        my.start();
        }
}


interrupt方法:它是Thread类中的方法,该方法的作用是:把线程的运行状态改变为中断,

但当对象调用它时,并不用立即让线程停止运行。这点是很多人都不注意,

很多人都认为:线程的中断就是让线程停止.这其实是错误的观点,因为这只是改变了

线程的中断状态,线程并不会立即停止运行,当我们在一个线程对象上调用interrupt()方法,

真正有影响的是wait,join,sleep方法,当然也包括它们的重载方法。

你说的这三个方法都不会抛出InterruptedException,但受影响的wait,join,sleep方法

以即它们的重载形式将会抛出InterruptedException异常。

也就是说,如果一个线程被调用了interrupt()后,它的状态是已中断的.

这个状态对于正在执行wait,join,sleep方法的线程会受到影响,从而抛出中断异常。


为什么调用interrupt方法不会立即使线程停止运行呢?

那是因为多线程的产生目的是提高CPU的利用率(提高处理数据的效率),

但要提高效率(一个更重要)的前提也要保证处理数据的完整性,

给你举个例子,

synchronized void {
         x = 3;
         y = 4;
}
这个方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到

x = 3;时,被调用了interrupt方法使线程停止了,即使是在同步块中,它也不会执行y=4,

而是直接停止了这样就产生了不完整的残废数据,而这个结果并不是我们想要的,

所以interrupt方法只是改变了线程的中断状态,并不会使线程停止,如果你要非要

使线程在此处停止的话,你可以使用stop方法(该方法是不建议使用的方法,

原因就是因为该方法会使线程产生不完整数据)。


isInterrupt方法的作用是:测试线程是否已经中断,如果已经中断,则返回 true;否则返回 false。

interrupted方法为一个静态方法:它的作用是测试当前线程是否已经中断,线程的中断状态 由该方法清除。
回复 使用道具 举报
付玉光 发表于 2013-3-7 16:28
有时,真郁闷,自己提的问题,自己回答,

关于第一个问题:

完了,不知道 怎样,把主题,改为《已解决》,,羞死我了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马