Java面试题精选二(多线程)

Java多线程

https://www.cnblogs.com/xiaowangbangzhu/p/10443289.html

1、java实现多线程的三种方式

(1)继承Thread来实现多线程

Java提供了一个超类Thread给我们继承extends,一旦继承了它,就可以通过重写(override)其中的run()方法来实现多线程,具体代码如下:

public class MyThread extends Thread{

    @Override

    public void run(){

        system.out.print(Thread.currentThread().getName());

    }

    public static void main(String[] args) throws IOException{

        Thread t1 = new MyThread();

        Thread t1 = new MyThread();

        t1.start();

        t2.start();

    }

}

(2)通过实现Runnable接口来实现,由于java的单继承特性,所以接口实现很受欢迎,有些类不可以继承超类的情况下,接口可以多实现,代码如下:

public class MyThread implements runnable{

    @Override

    public void run(){

        system.out.print(Thread.currentThread().getName());

    }

    public static void main(String[] args) throws IOException{

        Thread t1 = new MyThread();

        Thread t1 = new MyThread();

        t1.start();

        t2.start();

    }

}

上面这种是直接定义了类来实现Runnable方法,其实还可以变种为匿名内部类的方法来创建一个Thread,具体如下:

 

(3)通过callable来实现Thread

public class MyThread implements Callable<Integer>{

    public static void main(String[] args){

        MyThread t1 = new MyThread();

        FutureTask<Integer> future = new FutureTask<Integer>(t1);

        new Thread(future,"呵呵哒").start();

    }

    @Override

    public Integer call throws Exception(){

        system.out.print(Thread.currentThread().getName());
    
        return null;

    }

}

2、进程跟线程的区别

线程是进程的子集,一个进程可以有多个线程;每个线程在栈内存中都有单独存储数据的空间。

3、Thread类中run()跟start()有什么区别?

start()方法是启动新的线程,内部调用了run()方法,

直接调用run()方法只会在原来的线程中调用,没有新的线程启动。

4、Java中的volatile变量是什么?

volatile是一个特殊的修饰符,只有成员变量才能使用,保证了不同线程对这个变量的进行才做是的可见性,即一个线程改了某个变量的值,这个值对其他线程来说是立即可见的,通俗讲:这个修饰词保证了这个变量的实时性;

5、Java中的Runnable跟Callable有什么区别?

Runnable跟Callable都是创建多线程的方法,Callable的Call()方法可以返回返回值跟异常,runnable的run()方法没有,callable可以返回装载有计算结果的Future对象。

6、Java中notify和notifyAll有什么区别?

notify()方法不能直接唤醒某个具体线程,只有一个线程再等待的时候才有用武之地,而notifyAll()可以唤醒所有的线程并允许他们争夺锁,确保了至少有一个线程再运行。

7、为什么wait(),notify()和notifyAll()不定义在Thread里面呢?

因为Java提供的锁是对象级的而不是线程级的,每个对象都有锁,通过线程获取,如果线程需要等待某些锁那么调用对象中的wait()方法就有意义了。如果wait()方法定义在Thread类中,线程正在等待的是哪个锁 就不明显了。简单来说,由于wait,notify和notifyAll都是锁级别的操作,所以把他们定义在Object类中因为锁属于对象

8、java中的堆和栈有什么区别?

为什么把这个问题归类在多线程和并发面试题里面?因为栈是一块跟线程紧密相关的内存区域,每个线程都有自己的栈内存,用于存储本地变量,方法参数个栈调用,一个线程中存储的变量对其他线程是不可见的。而堆是所有线程共享的一片公共区域内存,对象都在堆里面创建,为了提升效率线程会从堆中弄一个缓存到自己的栈(也就是所谓的引用变量),如果多线程使用该变量就会有问题,这是就需要特殊的修饰符volatile变量来发挥作用,它要求线程从主存中提取变量的值。

9、什么是线程池?为什么要使用线程池?

创建线程要花费昂贵的资源,如果任务来了才创建线程,那么响应的时间会变长,而且一个进程能够创建的线程是有限的,为了方便,在程序启动的时候就创建若干线程响应处理,他们被称为线程池。Executor框架让你可以创建不同的线程池。

10、Java多线程中的死锁

死锁的发生具备以下四个条件:

  • 互斥条件:一个资源每次只能被一个进程使用。

  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

  • 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

避免死锁的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序、规定所有的线程申请资源必须以一定的顺序(升序或降序)做操作来避免死锁。

11、如何在Java中获取线程堆栈?

在 Windows你可以使用Ctrl + Break组合键来获取线程堆栈,Linux下用kill -3命令。你也可以用jstack这个工具来获取,它对线程id进行操作,你可以用jps这个工具找到id。

12、JVM中哪个参数是用来控制线程的堆栈大小?

-Xss 参数来控制线程的堆栈大小。

13、Java中synchronized 和 ReentrantLock 有什么不同?

Java在过去很长一段时间只能通过synchronized关键字来实现互斥,它有一些缺点。比如你不能扩展锁之外的方法或者块边界,尝试获取锁 时不能中途取消等。Java 5 通过Lock接口提供了更复杂的控制来解决这些问题。 ReentrantLock 类实现了 Lock,它拥有与 synchronized 相同的并发性和内存语义且它还具有可扩展性。

14、有三个线程T1、T2和T3,怎么确保他们按照顺序执行?

在线程中调用另外一个线程(T3调用T2,T2调用T1)

15、Thread中的yield()方法有什么用?

Yield方法可以暂停当前正在执行的线程对象,让其它有相同优先级的线程执行。它是一个静态方法而且只保证当前线程放弃CPU占用而不能保证使其它线程一定能占用CPU,执行yield()的线程有可能在进入到暂停状态后马上又被执行。

16、如果你提交任务,线程池已经满了,会发生什么?

会报错,这个问题问得很狡猾,许多程序员会认为该任务会阻塞直到线程池队列有空位。事实上如果一个任务不能被调度执行那么ThreadPoolExecutor’s submit()方法将会抛出一个RejectedExecutionException异常。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]和\[2\]提供了一些关于Java线程的面试。这些面试可以帮助你在面试前复习并提高你的理论知识。其中,引用\[1\]展示了两种创建多线程的方式,一种是继承Thread类,另一种是实现Runnable接口。继承Thread类的方式比较简单,但是限制了类的继承关系,而实现Runnable接口的方式更加灵活。引用\[3\]展示了使用Callable和FutureTask的方式创建多线程,并获取线程执行结果的示例。这种方式可以在多线程执行完毕后获取线程的返回结果。希望这些面试能够帮助你在面试中展示你的多线程知识和实战能力。 #### 引用[.reference_title] - *1* *3* [java2023多线面试](https://blog.csdn.net/weixin_68009402/article/details/130399986)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Java面试及答案整理汇总(2023最新版)](https://blog.csdn.net/Design407/article/details/129009269)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值