java面试线程问题_第1页
java面试线程问题_第2页
java面试线程问题_第3页
java面试线程问题_第4页
java面试线程问题_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、java 程序员面试中的多线程问题2012-05-28 09:12 | 10733次阅读 | 【已有 25条评论】 发表评论来源: fromdev | 收藏到我的网摘很多核心 java 面试题来源于多线程 (multi-threading)和集合框架(collections framework),理解核心线程概念时,娴熟的实际经验是必需的。这篇文章收集了 java 线程方面一些典型的问题, 这些问题经常被高级工程师所问到。0.java 中多线程同步是什么?在多线程程序下,同步能控制对共享资源的访问。如果没有同步,当一个 java 线程在修改一个共享变量时, 另外一个线程正在使用或者更新同一个变

2、量,这样容易导致程序出现错误的结果。1. 解释实现多线程的几种方法?一 java 线程可以实现 runnable 接口或者继承 thread 类来实现,当你打算多重继承时,优先选择实现 runnable 。2.thread.start ()与 thread.run ()有什么区别?thread.start () 方法(native)启动线程,使之进入就绪状态, 当 cpu 分配时间该线程时,由 jvm 调度执行 run ()方法。3. 为什么需要 run ()和 start ()方法,我们可以只用 run ()方法来完成任务吗?我们需要 run ()&start ()这两个方法是因为

3、jvm 创建一个单独的线程不同于普通方法的调用,所以这项工作由线程的 start 方法来完成,start 由本地方法实现,需要显示地被调用,使用这俩个方法的另外一个好处是任何一个对象都可以作为线程运行,只要实现了runnable 接口,这就避免因继承了 thread 类而造成的 java 的多继承问题。4. 什么是 threadlocal 类,怎么使用它?threadlocal 是一个线程级别的局部变量,并非“本地线程”。threadlocal 为每个使用该变量的线程提供了一个独立的变量副本,每个线程修改副本时不影响其它线程对象的副本(译者注 ) 。下面是线程局部变量 (threadlocal

4、 variables)的关键点:一个线程局部变量 (threadlocal variables)为每个线程方便地提供了一个单独的变量。threadlocal 实例通常作为静态的私有的(private static)字段出现在一个类中,这个类用来关联一个线程。当多个线程访问 threadlocal 实例时,每个线程维护 threadlocal 提供的独立的变量副本。常用的使用可在 dao 模式中见到, 当 dao 类作为一个单例类时, 数据库链接 (connection)被每一个线程独立的维护,互不影响。(基于线程的单例 ) threadlocal 难于理解,下面这些引用连接有助于你更好的理解它

5、。good article on threadlocal on ibm developerworks 、 理解threadlocal 、 managing data : good example 、 refer java api docs5. 什么时候抛出 invalidmonitorstateexception 异常,为什么?调用 wait ()/notify ()/notifyall ()中的任何一个方法时,如果当前线程没有获得该对象的锁,那么就会抛出illegalmonitorstateexception 的异常 ( 也就是说程序在没有执行对象的任何同步块或者同步方法时,仍然尝试调用 w

6、ait ()/notify ()/notifyall () 时)。由于该异常是 runtimeexcpetion 的子类,所以该异常不一定要捕获 (尽管你可以捕获只要你愿意). 作为runtimeexception ,此类异常不会在 wait (),notify (),notifyall () 的方法签名提及。6.sleep ()、suspend () 和 wait ()之间有什么区别?thread.sleep ()使当前线程在指定的时间处于“非运行”(not runnable)状态。线程一直持有对象的监视器。比如一个线程当前在一个同步块或同步方法中, 其它线程不能进入该块或方法中。如果另一线

7、程调用了 interrupt ()方法,它将唤醒那个“睡眠的”线程。注意:sleep () 是一个静态方法。这意味着只对当前线程有效,一个常见的错误是调用t.sleep (), (这里的 t 是一个不同于当前线程的线程) 。即便是执行 t.sleep (),也是当前线程进入睡眠,而不是t线程。 t.suspend ()是过时的方法,使用 suspend ()导致线程进入停滞状态,该线程会一直持有对象的监视器,suspend () 容易引起死锁问题。object.wait ()使当前线程出于“不可运行”状态,和 sleep ()不同的是 wait 是 object 的方法而不是 thread 。

8、调用 object.wait () 时,线程先要获取这个对象的对象锁,当前线程必须在锁对象保持同步,把当前线程添加到等待队列中,随后另一线程可以同步同一个对象锁来调用 object.notify (),这样将唤醒原来等待中的线程,然后释放该锁。基本上 wait ()/notify () 与 sleep ()/interrupt ()类似,只是前者需要获取对象锁。7. 在静态方法上使用同步时会发生什么事?同步静态方法时会获取该类的“class”对象,所以当一个线程进入同步的静态方法中时, 线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法, 因为多个线程可以同

9、时访问不同实例同步实例方法。8. 当一个同步方法已经执行, 线程能够调用对象上的非同步实例方法吗?可以,一个非同步方法总是可以被调用而不会有任何问题。实际上,java 没有为非同步方法做任何检查,锁对象仅仅在同步方法或者同步代码块中检查。 如果一个方法没有声明为同步,即使你在使用共享数据 java 照样会调用, 而不会做检查是否安全, 所以在这种情况下要特别小心。一个方法是否声明为同步取决于临界区访问(critial section access),如果方法不访问临界区(共享资源或者数据结构 )就没必要声明为同步的。下面有一个示例说明: common 类有两个方法 synchronizedme

10、thod1()和 method1() ,mythread 类在独立的线程中调用这两个方法。public class common public synchronized void synchronizedmethod1() system.out.println (synchronizedmethod1 called); try thread.sleep (1000); catch (interruptedexception e) e.printstacktrace (); system.out.println (synchronizedmethod1 done); public void me

11、thod1() system.out.println (method 1 called); try thread.sleep (1000); catch (interruptedexception e) e.printstacktrace (); system.out.println (method 1 done); public class mythread extends thread private int id = 0; private common common; public mythread (string name, int no, common object) super(n

12、ame); common = object ; id = no; public void run () system.out.println (running thread + this.getname (); try if (id = 0) common.synchronizedmethod1(); else common.method1(); catch (exception e) e.printstacktrace (); public static void main (string args) common c = new common (); mythread t1 = new m

13、ythread (mythread-1, 0, c); mythread t2 = new mythread (mythread-2, 1, c); t1.start (); t2.start (); 这里是程序的输出:running threadmythread-1 synchronizedmethod1 called running threadmythread-2 method 1 called synchronizedmethod1 done method 1 done 结果表明即使 synchronizedmethod1()方法执行了, method1() 也会被调用。9. 在一个对

14、象上两个线程可以调用两个不同的同步实例方法吗?不能, 因为一个对象已经同步了实例方法, 线程获取了对象的对象锁。所以只有执行完该方法释放对象锁后才能执行其它同步方法。看下面代码示例非常清晰: common 类有 synchronizedmethod1()和synchronizedmethod2() 方法, mythread 调用这两个方法。public class common public synchronized void synchronizedmethod1() system.out.println (synchronizedmethod1 called); try thread.sl

15、eep (1000); catch (interruptedexception e) e.printstacktrace (); system.out.println (synchronizedmethod1 done); public synchronized void synchronizedmethod2() system.out.println (synchronizedmethod2 called); try thread.sleep (1000); catch (interruptedexception e) e.printstacktrace (); system.out.pri

16、ntln (synchronizedmethod2 done); public class mythread extends thread private int id = 0; private common common; public mythread (string name, int no, common object) super(name); common = object ; id = no; public void run () system.out.println (running thread + this.getname (); try if (id = 0) commo

17、n.synchronizedmethod1(); else common.synchronizedmethod2(); catch (exception e) e.printstacktrace (); public static void main (string args) common c = new common (); mythread t1 = new mythread (mythread-1, 0, c); mythread t2 = new mythread (mythread-2, 1, c); t1.start (); t2.start (); 10. 什么是死锁死锁就是两个或两个以上的线程被无限的阻塞,线程之间相互等待所需资源。这种情况可能发生在当两个线程尝试获取其它资源的锁,而每个线程又陷入无限等待其它资源锁的释放,除非一个用户进程被终止。就 javaapi 而言,线程死锁可能发生在一下情况。当两个线程相互调用 thread.join () 当两个线程使用嵌套的同步块,一个线

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论