java基础知识(5)—一起加强加强java基础吧

44.请写出你最常见到的 你最常见到的 5 个 runtime exception

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


45.JAVA  语言如何进行异常处理,关键字: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;
public class 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无法得不到锁。

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!");
}
}
}
}


48.同步和异步有何异同,在什么情况下分别使用他们?举例说明。

如果数据将在线程间共享。 例如正在写的数据以后可能被另一个线程读到, 或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。当应用程序在对象上调用了一个需要花费很长时间来执行的方法, 并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。


49.多线程有几种实现方法?同步有几种实现方法?

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


50.启动一个线程是用 run() 还是 start()?

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


51.当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对象的其它方法 ?

分几种情况:
1. 其他方法前是否加了 synchronized 关键字,如果没加,则能。
2. 如果这个方法内部调用了 wait,则可以进入其他 synchronized 方法。
3. 如果其他个方法都加了 synchronized 关键字,并且内部没有调用 wait,则不能。

4. 如果其他方法是 static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是 this。


52. 线程的基本概念、线程的基本状态以及状态之间的关系

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


53.简述 synchronized 和 和 java.util.concurrent.locks.Lock  的异同

主要相同点:Lock 能完成 synchronized 所实现的所有功能
主要不同点:Lock 有比 synchronized 更精确的线程语义和更好的性能。synchronized 会自动释放锁,而 Lock 一定要求程序员手工释放,并且必须在 finally 从句中释放。Lock 还有更强大的功能,例如,它的 tryLock 方法可以非阻塞方式去拿锁。


54.设计 4  个线程,其中两个线程每次对 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();
}
}
}
}


55.子线程循环 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 class Business

{
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();
}
}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值