Java程序员面试中的多线程问题
0、Java中多线程同步是什么?
在多线程程序下,同步能控制对共享资源的访问。如果没有同步,当一个Java线程在修改一个共享变量时,另外一个线程正在使用或者更新同一个变量,这样容易导致程序出现错误的结果。
1、解释实现多线程的几种方法?
一Java线程可以实现Runnable接口或者继承Thread类来实现,当你打算多重继承时,优先选择实现Runnable。
2、t()与()有什么区别?
t()方法(native)启动线程,使之进入就绪状态,当cpu分配时间该线程时,由JVM调度执行run()方法。
3、为什么需要run()和start()方法,我们可以只用run()方法来完成任务吗?
我们需要run()&start()这两个方法是因为JVM创建一个单独的线程不同于普通方法的调用,所以这项工作由线程的start方法来完成,start由本地方法实现,需要显示地被调用,使用这俩个方法的另外一个好处是任何一个对象都可以作为线程运行,只要实现了Runnable接口,这就避免因继承了Thread类而造成的Java的多继承问题。
4、什么是ThreadLocal类,怎么使用它?
ThreadLocal是一个线程级别的局部变量,并非“本地线程”。ThreadLocal为每个使用该变量的线程提供了一个独立的'变量副本,每个线程修改副本时不影响其它线程对象的副本(译者注)。
下面是线程局部变量(ThreadLocal variables)的关键点:
一个线程局部变量(ThreadLocal variables)为每个线程方便地提供了一个单独的变量。
ThreadLocal实例通常作为静态的私有的(private static)字段出现在一个类中,这个类用来关联一个线程。
当多个线程访问ThreadLocal实例时,每个线程维护ThreadLocal提供的独立的变量副本。
常用的使用可在DAO模式中见到,当DAO类作为一个单例类时,数据库链接(connection)被每一个线程独立的维护,互不影响。(基于线程的单例)
5、什么时候抛出InvalidMonitorStateException异常,为什么?
调用wait()/notify()/notifyAll()中的任何一个方法时,如果当前线程没有获得该对象的锁,那么就会抛出IllegalMonitorStateException的异常(也就是说程序在没有执行对象的任何同步块或者同步方法时,仍然尝试调用wait()/notify()/notifyAll()时)。由于该异常是RuntimeExcpetion的子类,所以该异常不一定要捕获(尽管你可以捕获只要你愿意).作为RuntimeException,此类异常不会在wait(),notify(),notifyAll()的方法签名提及。
6、Sleep()、suspend()和wait()之间有什么区别?
p()使当前线程在指定的时间处于“非运行”(Not Runnable)状态。线程一直持有对象的监视器。比如一个线程当前在一个同步块或同步方法中,其它线程不能进入该块或方法中。如果另一线程调用了 interrupt()方法,它将唤醒那个“睡眠的”线程。
注意:sleep()是一个静态方法。这意味着只对当前线程有效,一个常见的错误是调用p(),(这里的t是一个不同于当前线程的线程)。即便是执行p(),也是当前线程进入睡眠,而不是t线程。end()是过时的方法,使用suspend()导致线程进入停滞状态,该线程会一直持有对象的监视器,suspend()容易引起死锁问题。
()使当前线程出于“不可运行”状态,和sleep()不同的是wait是object的方法而不是thread。调用 ()时,线程先要获取这个对象的对象锁,当前线程必须在锁对象保持同步,把当前线程添加到等待队列中,随后另一线程可以同步同一个对象锁来调用fy(),这样将唤醒原来等待中的线程,然后释放该锁。基本上wait()/notify()与sleep() /interrupt()类似,只是前者需要获取对象锁。
7、在静态方法上使用同步时会发生什么事?
同步静态方法时会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。
8、当一个同步方法已经执行,线程能够调用对象上的非同步实例方法吗?
可以,一个非同步方法总是可以被调用而不会有任何问题。实际上,Java没有为非同步方法做任何检查,锁对象仅仅在同步方法或者同步代码块中检查。如果一个方法没有声明为同步,即使你在使用共享数据Java照样会调用,而不会做检查是否安全,所以在这种情况下要特别小心。一个方法是否声明为同步取决于临界区访问(critial section access),如果方法不访问临界区(共享资源或者数据结构)就没必要声明为同步的。
下面有一个示例说明:Common类有两个方法synchronizedMethod1()和method1(),MyThread类在独立的线程中调用这两个方法。
public class Common {
public synchronized void synchronizedMethod1() {
tln("synchronizedMethod1 called");
try {
p(1000);
} catch (InterruptedException e) {
tStackTrace();
}
tln("synchronizedMethod1 done");
}
public void method1() {
tln("Method 1 called");
try {
p(1000);
} catch (InterruptedException e) {
tStackTrace();
}
tln("Method 1 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() {
tln("Running Thread" + ame());
try {
if (id == 0) {
hronizedMethod1();
} else {
od1();
}
} catch (Exception e) {
tStackTrace();
}
}
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);
t();
t();
}
}
这里是程序的输出:
-
应对面试“十大必考题”
面试时,有几个问题是公司面试人员常常会提出的,针对这些问题好好准备,在面试时也就不会哑口无言,无言以对了,下面就面试十大必考题做出分析:(1)为什么想进本公司?这通常是面试官最先问到的问题。此时面试官就开始评断录用与否了,建议大家先判断自己去应征的工作性质,是专...
-
大学生在求职面试应答中最忌讳的是什么
许多大学毕业生,在求职应试过程中表现得特别积极,他们在第一关笔试中都很容易过关,但是在面试过程中,就会被一些问题难住,有些同学以为这没有什么大不了的,只要自己有本事,不怕用人单位不识货,这种思想极其错误。因为一些不必要的失误,往往会导致用人单位对自己产生不好...
-
空乘面试问题
空乘面试问题1空乘面试问题总汇!!!为什么要做一名空姐?你对空姐的工作有哪些了解?你有哪些特长和爱好?在家里是否帮助父母做家务?如果在飞机上遇到不讲理的客人你会怎么做?你考虑过做空姐的辛苦吗?如果你被我公司录取,你准备如何做一名合格的空乘人员?做一名优秀的空乘人...
-
题目:描述一下你个人的管理方式
描述一下你个人的管理方式。答:我重复别人告诉我的东西,但我用一种有助于他们独立发现问题和找到答案的方式重新归纳它们。有时,我只是不断地提问,直到他们找到解决方法为止。这种方法,是我从一位成功从事审讯工作的律师朋友那里学来的。谈你的管理方式和你与同事、...