java基础知识3

38、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后? 
也许你的答案是在return之前,但往更细地说,我的答案是在return中间执行,请看下面程序代码的运行结果:
public classTe s t {
/**
* @paramargs add by zxx ,Dec 9, 2008
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out. println(new Test().test());;

static int test()

intx = 1;
try

Return x; 

finally

++x; 



---------执行结果 ---------1 

运行结果是1,为什么呢?主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。


40、final, finally, finalize的区别。
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用


41、运行时异常与一般异常有何异同?
异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java 编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。


42、error和exception有什么区别? 
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。


43、Java中的异常处理机制的简单原理和应用。
异常是指java 程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间、地点、人物、情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。
Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Error表示
应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。
java 为系统异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常,而系统异常可以处理也可以不处理,所以,编译器不强制用try..catch处理或用throws声明,所以系统异常也称为unchecked异常。提示答题者:就按照三个级别去思考:虚拟机必须宕机的错误,程序可以死掉也可以不死掉的错误,程序不应该死掉的错误;


44、请写出你最常见到的5个runtime exception。
这道题主要考你的代码量到底多大,如果你长期写代码的,应该经常都看到过一些系统方面的异常,你不一定真要回答出5个具体的系统异常,但你要能够说出什么是系统异常,以及几个系统异常就可以了,当然,这些异常完全用其英文名称来写是最好的,如果实在写不出,那就用中文吧,有总比没有强!所谓系统异常,就是…..,它们都是RuntimeException的子类,在jdk doc 中查RuntimeException类,就可以看到其所有的子类列表,也就是看到了所有的系统异常。我比较有印象的系统异常有:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。


45、J AVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
throws捕获并向外抛出异常
throw抛出异常
try catch是内部捕获异常并做自定义处理
finally是无论是否有异常都会被处理的语句,除非在finally前存在被执行的System.exit(int i)时除外


46、java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
java5以前,有如下两种:
第一种:
new Thread(){}.start();这表示调用Thread子类对象的run方法,new Thread(){}表示一个Thread的匿名子类的实例对象,子类加上run方法后的代码如下:
new Thread(){
public void run(){

}.start();
第二种:
new Thread(new Runnable(){}).start();这表示调用Thread对象接受的Runnable对象的run方法,new Runnable(){}表示一个Runnable的匿名子类的实例对象,runnable的子类加上run方法后的代码如下:
new Thread(new Runnable(){
public voidrun(){
}    

).start();
从java5开始,还有如下一些线程池创建多线程的方式:
ExecutorService pool = Executors.newFixedThreadPool(3)
for(int i=0;i<10;i++)

pool.execute(newRunable(){public void run(){}});

Executors.newCachedThreadPool().execute(new Runable(){publicvoid run(){}});
Executors.newSingleThreadExecutor().execute(new Runable(){publicvoid run(){}});
有两种实现方法,分别使用new Thread()和new Thread(runnable)形式,第一种直接调用thread的run方法,所以,我们往往使用Thread子类,即new SubThread()。第二种调用runnable的run方法。
有两种实现方法,分别是继承Thread类与实现Runnable接口
用synchronized关键字修饰同步方法
反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。


47、sleep()和 wait()有什么区别? 
(网上的答案:sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放
对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入
对象锁定池准备获得对象锁进入运行状态。)

sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。对于wait的讲解一定要配合例子代码来说明,才显得自己真明白。
package com.huawei.interview;
publicclass MultiThread {
/**
* @paramargs
*/
public static voidmain(String[] args) {
// TODO Auto-generated method stub
new Thread(newThread1()).start();
try{ 
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catchblock
e.printStackTrace();

new Thread(newThread2()).start();    

private static classThread1implements Runnable

@Override
public void run() {
// TODO Auto-generated methodstub
//由于这里的Thread1和下面的Thread2内部run方法要用同一对象作为监视器,我们这里不能用this,因为在Thread2里面的this和这个Thread1的this不是同一个对象。我们用
MultiThread.class这个字节码对象,当前虚拟机里引用这个变量时,指向的都是同一个对象。
synchronized (MultiThread.class){
System.out.println("enterthread1...");
System.out.println("thread1is waiting");
try{ 
//释放锁有两种方式,第一种方式是程序自然离开监视器的范围,也就是离开了synchronized关键字管辖的代码范围,另一种方式就是在synchronized关键字管辖的代码内部调用监视器对象的wait方法。这里,使用wait方法释放锁。
MultiThread.class.wait();
} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();

System.out.println("thread1is going on...");
System.out.println("thread1is being over!");       



private static classThread2implements Runnable

@Override
public void run() {
// TODO Auto-generated methodstub
synchronized (MultiThread.class){
System.out.println("enterthread2...");
System.out.println("thread2notify other thread can release wait status..");
//由于notify方法并不释放锁,即使thread2调用下面的sleep方法休息了10毫 秒 ,但thread1仍然不会执行,因为thread2没有释放锁,所以Thread1无法得不到锁。
飞米网—java技术交流 java教程 www.feimy.com
MultiThread.class.notify();
System.out.println("thread2is sleeping ten millisecond...");
try{ 
Thread.sleep(10);
} catch (InterruptedExceptione) {
// TODO Auto-generatedcatch block
e.printStackTrace();

System.out.println("thread2is going on...");
System.out.println("thread2is being over!");


}  


49. 下面两个方法同步吗?(自己发明)
class Test


synchronizedstatic  void say Hello3()

}  
synchronizedvoid  getX(){}


50、多线程有几种实现方法?同步有几种实现方法? 
多线程有两种实现方法,分别是继承Thread类与实现Runnable接口
同步的实现方面有两种,分别是synchronized,wait与notify
wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉
InterruptedException(中断异常)异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。


51、启动一个线程是用run()还是start()? .
启动一个线程是调用start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。


52、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 
分几种情况:
1. 其他方法前是否加了synchronized关键字,如果没加,则能。
2. 如果这个方法内部调用了wait,则可以进入其他synchronized方法。
3. 如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。
4. 如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。


53、线程的基本概念、线程的基本状态以及状态之间的关系
一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个cpu,它怎么能够同时执行多段程序呢?这是从宏观上来看的,cpu一会执行a线索,一会执行b线索,切换时间很快,给人的感觉是a,b在同时执行,好比大家在同一个办公室上网,只有一条链接到外部网线,其实,这条网线一会为a传数据,一会为b传数据,由于切换时间很短暂,所以,大家感觉都在同时上网。
状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。


54、简述synchronized和java.util.concurrent.locks.Lock的异同?
主要相同点:Lock能完成synchronized所实现的所有功能
主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。
举例说明(对下面的题用lock 进行了改写):
package com.huawei.interview;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
publicclass ThreadTest {

/**
* @paramargs
*/
private int j;
private Lock lock =newReentrantLock();
public static voidmain(String[] args) {
// TODO Auto-generated method stub
ThreadTest tt = new ThreadTest();
for(int i=0;i<2;i++)

new Thread(tt.new Adder()).start();
new Thread(tt.new Subtractor()).start();


private class SubtractorimplementsRunnable

@Override
public void run() {
// TODO Auto-generated methodstub
while(true) 

/*synchronized (ThreadTest.this) {       
System.out.println("j--="+ j--);
//这里抛异常了,锁能释放吗?
}*/
lock.lock();
try


System.out.println("j--="+ j--);
}finally

lock.unlock();




private class AdderimplementsRunnable

@Override
public void run() {
// TODO Auto-generated methodstub
while(true) 

/*synchronized (ThreadTest.this) {
System.out.println("j++="+ j++); 
}*/
lock.lock();
try

System.out.println("j++="+ j++);
}finally

lock.unlock();
}            
}         





55、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少
1。写出程序。
以下程序使用内部类实现线程,对j 增减的时候没有考虑顺序问题。
public class ThreadTest1

private int j;
public static void main(String args[]){
ThreadTest1 tt=newThreadTest1();
Inc inc=tt.new Inc();
Dec dec=tt.new Dec();
for(inti=0;i<2;i++){
Thread t=newThread(inc);
t.start();
t=new Thread(dec);
t.start();


private synchronized void inc(){
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);

private synchronized void dec(){
j--; 
System.out.println(Thread.currentThread().getName()+"-dec:"+j);

class Inc implements Runnable{

public void run(){
for(inti=0;i<100;i++){
inc();



class Dec implements Runnable{
public void run(){
for(inti=0;i<100;i++){
dec();




----------随手再写的一个-------------class A

JManger j =new JManager();
main()

new A().call();

void call

for(int i=0;i<2;i++)

new Thread(
newRunnable(){ public void run(){while(true){j.accumulate()}}}
).start();

new Thread(newRunnable(){ public void run(){while(true){j.sub()}}}).start();



class JManager

private j = 0;
public synchronized voidsubtract()

j--} 
public synchronized voidaccumulate()

j++;


56、子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。
最终的程序代码如下:
public class ThreadTest {
/**
* @paramargs
*/

public static voidmain(String[] args) {
// TODO Auto-generated method stub
new ThreadTest().init();

public void init()

final Business business =newBusiness(); 
new Thread(
new Runnable()

public voidrun() {
for(inti=0;i<50;i++)

business.SubThread(i);
}                   


).start();
for(int i=0;i<50;i++)

business.MainThread(i);
}     

private classBusiness 


booleanbShouldSub=true;//这里相当于定义了控制该谁执行的一个信号灯
public synchronized voidMainThread(int i)

if(bShouldSub) 
try{ 
this.wait();
} catch(InterruptedException e) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}     
for(int j=0;j<5;j++)

System.out.println(Thread.currentThread().getName()+ ":i=" + i +",j=" + j);

bShouldSub=true; 
this.notify();

public synchronized voidSubThread(int i)

if(!bShouldSub) 
try{ 
this.wait();
} catch (InterruptedExceptione) {
// TODO Auto-generatedcatch block
e.printStackTrace();
}  

for(intj=0;j<10;j++)

System.out.println(Thread.currentThread().getName()+ ":i=" + i +",j=" + j);

bShouldSub=false;            
this.notify();          



备注:不可能一上来就写出上面的完整代码,最初写出来的代码如下,问题在于两个线程的代码要参照同一个变量,即这两个线程的代码要共享数据,所以,把这两个线程的执行代码
搬到同一个类中去:
package com.huawei.interview.lym;
publicclass ThreadTest {
private static booleanbShouldMain=false; 
public static void main(String[]args) {
// TODO Auto-generated method stub
/*new Thread(){
public void run()

for(int i=0;i<50;i++)

for(int j=0;j<10;j++)

System.out.println("i="+ i + ",j=" + j);


}            

}.start();*/     
//final String str = newString("");
new Thread(
new Runnable() 

public voidrun()

for(inti=0;i<50;i++)

synchronized(ThreadTest.class) {
if(bShouldMain) 

try{ 
ThreadTest.class.wait();}
catch(InterruptedException e) {
e.printStackTrace();


for(intj=0;j<10;j++)

System.out.println(
Thread.currentThread().getName()+
"i="+ i + ",j=" + j);


bShouldMain= true; 
ThreadTest.class.notify();
}                       
}   


).start();
for(int i=0;i<50;i++)

synchronized (ThreadTest.class){
if(!bShouldMain) 

try{ 
ThreadTest.class.wait();}
catch(InterruptedException e) {
e.printStackTrace();

}            
for(intj=0;j<5;j++)

System.out.println(
Thread.currentThread().getName()+                     
"i=" + i +",j=" + j);

bShouldMain=false; 
ThreadTest.class.notify();            
}         




下面使用jdk5中的并发库来实现的:
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
public class ThreadTest

private static Locklock = new ReentrantLock();
private staticCondition subThreadCondition = lock.newCondition();
private staticboolean bBhouldSubThread = false;
public static voidmain(String [] args)

ExecutorServicethreadPool = Executors.newFixedThreadPool(3);
threadPool.execute(newRunnable(){
publicvoid run()

for(inti=0;i<50;i++)

lock.lock();                                
try
{                                
if(!bBhouldSubThread) 
subThreadCondition.await();
for(intj=0;j<10;j++)

System.out.println(Thread.currentThread().getName()+ ",j=" + j);


bBhouldSubThread= false;
subThreadCondition.signal();
}catch(Exceptione)
{                                       

finally

lock.unlock();

}                  

});
threadPool.shutdown();
for(inti=0;i<50;i++)

lock.lock();                                
try
{    
if(bBhouldSubThread)
subThreadCondition.await();                       
for(intj=0;j<10;j++)

System.out.println(Thread.currentThread().getName()+ ",j=" + j);

bBhouldSubThread= true;
subThreadCondition.signal();                            
}catch(Exceptione)
{                                       


finally

lock.unlock();
}                          




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值