java并发面试题

1. 线程与进程的区别

(1)进程是具有一定独立功能的程序,是操作系统进行资源分配和调度的一个独立单位;

线程是进程的一个实体,是CPU调度和分派的基本单位,是比进程更小的能独立运行的基本单位。

(2)进程是执行着的应用程序,而线程是进程内部的一个执行序列。一个进程可以有多个线程。线程又叫做轻量级进程。

(3)进程在执行时通常拥有独立的内存单元,而线程之间可以共享内存。

 

2.实现多线程程序的两种方法

实现多线程不需要在源程序前使用import语句显示导入thread类

方式1:继承Thread类。

 

         A:自定义类MyThread继承Thread类。

         B:MyThread类里面重写run():run Alt+/

         C:创建对象

         D:启动线程

方式2:实现Runnable接口的步骤:

         A:自定义类MyRunnable实现Runnable接口

         B:重写run()方法

         C:创建MyRunnable类的对象

         D:创建Thread类的对象,并把C步骤的对象作为构造参数传递

 

3.Thread类要重写run()方法,为什么呢?

不是类中的所有代码都需要被线程执行的。

而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码。

 

4. run()和start()的区别?

run():仅仅是封装被线程执行的代码,直接调用是普通方法

start():首先启动了线程,调用该线程的run()方法。

 

5.Volatile的作用,实现原理,什么情况用

(1)用来修饰被不同线程访问和修改的变量,Volatile是轻量级的synchronized

(2)Volatile关键字为实例域的同步访问提供了一种免锁机制。生成的汇编代码多了一个lock前缀指令

(3)可以解决可见性、有序性(避免指令重排)。

 

6.线程的生命周期图

     新建 -- 就绪(已经启动,但是没有执行权) -- 运行 -- 死亡

     新建 -- 就绪 -- 运行 -- 阻塞(没有执行权,回到就绪) -- 就绪 -- 运行 -- 死亡

 

7.锁对象问题

(1)普通同步方法,锁是当前实例对象

(2)静态同步方法,锁是当前类的class对象

(3)同步方法块,锁是括号里面的对象:任意对象

 

8.同步方法和同步代码块的区别是什么?

在Java语言中,每一个对象有一把锁。线程可以使用synchronized关键字来获取对象上的锁。synchronized关键字可应用在方法级别(粗粒度锁)或者是代码块级别(细粒度锁)。

java 中每个对象都有一把锁, 线程可以通过 synchronized 关键字来获取对象上的锁

同步方法(粗粒度锁):

(1)修饰一般方法: public synchronized void method(){...}, 获取的是当前调用对象 this 上的锁

(2) 修饰静态方法: public static synchronized voidmethod (){...}, 获取当前类的字节码对象上的锁

同步代码块(细粒度锁):

         synchronized ( obj ) {...}, 同步代码块可以指定获取哪个对象上的锁, obj 任意

 

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

不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入。因为非静态方法上的synchronized修饰符要求执行方法时要获得对象的锁,如果已经进入A方法说明对象锁已经被取走,那么试图进入B方法的线程就只能在等锁池(注意不是等待池哦)中等待对象的锁。

 

10.线程安全的类

         StringBuffer sb = new StringBuffer();

         Vector<String> v = newVector<String>();// Vector基本不用

         Hashtable<String, String> h = newHashtable<String, String>();

 

11.线程安全的ArrayList

         List<String> list1 = newArrayList<String>();// 线程不安全

         List<String> list2 =Collections.synchronizedList(new ArrayList<String>()); // 线程安全

 

12. Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?

sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复。

wait()是Object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(waitpool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。

 

13.线程的sleep()方法和yield()方法有什么区别?

(1)sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;

(2)线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;

(3)sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;

(4)sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。

 

 

14.请说出与线程同步以及线程调度相关的方法

- wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;

- sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;

- notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关;

- notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;

 

15. 什么是不可变对象,它对写并发应用有什么帮助?

不可变对象(英语:Immutable object)是一种对象,在被创造之后,它的状态就不可以被改变。任何试图改变改对象状态的操作都会生成新的对象,老的对象保持不变。

在多线程并发的情况下 ,多个线程读取共享变量是安全的,但是写操作肯定会冲突, 由于不可变对象不可更改,并发时不需要其他额外的同步保证,故相比其他的锁同步等方式的并发性能要好。

 

16.现在有t1、t2、t3三个线程,你怎样保证t2在t1执行完后执行,t3在t2执行完后执行?

在t3线程中, 调用t2.join , 在t2中,调用t1.join

 

17.进程之间的通信方式。

# 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。

# 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。

# 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

# 消息队列( message queue ) :消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

# 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

# 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。

# 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同主机间的进程通信。

18.死锁的必要条件,怎么处理死锁。

当计算机系统同时具备下面4个条件时,会发生死锁:

(1)互斥条件。

某个资源在一段时间内只能由一个进程占有

(2)占有且等待条件。

进程至少已经占有一个资源,但又申请新的资源。

(3)不可抢占条件。

一个进程所占有的资源在用完之前,其他进程不能强行夺走该资源

(4)循环等待条件。

 

预防死锁:破坏四个必要条件之一

避免死锁:安全序列:进程按照某种次序分配单元

               银行家算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值