java多线程的一些问题

1. 什么是线程?java

线程是操做系统中运算调度的最小单位,算法

包含在进程中;数据库

使用多线程在处理密集任务的时候能够提速。Java语言对多线程提供了很好的支持。编程

 

2. 线程和进程的区别?缓存

一个进程能够有不少线程,每条线程执行不一样的任务。安全

不一样进程有不一样的内存空间,全部的线程共享一块内存空间。性能优化

每一个线程都有单独的栈内存存储本地数据。服务器

 

3. 线程的实现方式?多线程

继承Thread类,调用Runnable接口;架构

Java继承的单根性,实现Runnable接口,重写run()方法实现线程。

 

4. Start和Run的区别?

Start启动新建立的线程,start内部调用run方法;

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

 

5. Runable和Callable有什么不一样?

Runnable从jdk1.0就开始有的,Callable是jdk1.5增长的;

Callable的call()方法能够有返回值和抛出异常,Runnable的run()方法没有这些功能;

Callable还能够返回装载有计算结果的Future对象。

 

6. Java的内存模型?

Java的内存模型规定和指引了java程序在不一样的内存架构,CPU和操做系统之间有肯定性的行为;

它们在多线程的状况下尤为重要,内存模型为多线程之间的可见性提供了保证;

                 

内存模型中有一块共享的内存空间——主内存,持有全部线程的共享变量,各个线程的的本地内存持有的仅是共享变量的副本;

当线程A发生变化的时候,将副本信息刷新到主内存中;线程B在主内存中读取线程A改变的信息。

 

7. volatile变量是什么?

  在并发编程中缺乏同步的状况下,多线程对成员变量的操做是透明的,其它线程可见;

vlatile能够保证下一个读取操做会在前一个写操做以后发生,只有成员变量才能使用它。

 

8. 什么是线程安全?Vector是一个线程安全类么?

多线程状况下,同时执行一段代码,运行结果和单线程保持一致,就是线程安全;

Vector是用同步方法来实现线程安全的;ArrayList不是线程安全的;

 

9.  Java中的竞态条件?例子

多线程对一些资源的竞争,首先要执行的程序竞争失败从新排队,致使整个流程没有按照预期的顺序处理,出现一些不肯定的,很难发现的bug,这种状况是竞态条件;

例如:无序处理

 

10. Java中如何中止一个线程?

没有中止线程的API;

JDK1.0提供,stop(),suspend(),resume()等控制线程的方法,已经被被弃用,太暴力;

当run()或者call()方法执行完以后线程会自动结束;

手动结束,能够调用interrupt()来中断线程,有一个中断标志。

 

11. 一个线程发生异常时会怎样?

没有捕获线程会中止执行,抛异常UncaughtExceptionHandler;

JVM内部提供了Thread.getUncaughtExceptionHandler()来查询线程是否设置异常处理。

 

12. 如何实现两个线程之间共享数据?

能够经过共享对象来实现;

 

13. Notify和NotifyAll的区别?

Notify()唤醒单个线程;

notifAll()唤醒全部的线程,让他们争夺锁。

 

14. 为何wait,notify,notifyall这些方法不在thread类里面?

这些方法防治Object类里面;

由于java提供的锁是对象级的锁,而不是线程级的锁,每一个对象都有锁,经过线程得到;

定义在Thread里面,不符合对象锁的设计。

 

15. 什么是ThreadLocal变量?

本地线程变量;

让每个线程都有ThredLocal,竞态条件就被消除;

对于频繁建立对象的线程,使用它能够减小对象的建立个数,在线程本地内存中持有变量副本,不用每次都建立;

例如:使用ThreadLocal可让SimpleDateFormat变成线程安全的;

 

16. Interrupted和isInterrupted方法的区别?

前者会将中断状态清除,后者不会;

Java多线程中的中断机制是用内部标识来实现的,调用interrupt来中断一个线程会设置一个中断标志true,查询中断状态的时候,标志会被清除;

后者用来查询中断状态不会改变中断状态标志;

前者是静态的,后者是非静态的;

 

17. 为何wait和notify方法要在同步代码块中调用?

强制要求的,不这样作会抛异常IllegalMonitorStateException;

避免两者之间产生竞态条件;

 

18. Java中的同步集合与并发集合的区别?

同步集合与并发集合都为对线程提供了合适的线程安全的集合,并发集合扩展性更高;

Java5以前,只有同步集合,且在多线程并发的时候会致使争抢,阻碍看程序的扩展性;

Java5以后,出现并发集合,例如ConcurrentHashMap,不只提供线程安全,还用锁分离和内部分区等,扩展性更好。

 

19. Java中堆和栈有什么不一样?

栈是一块和线程紧密相关的内存区域,每一个线程都有本身的栈内存,用于存储本地变量,方法参数和栈调用,一个栈中存储的变量对其它线程不可见;

堆是全部线程共享的一片公共内存区域,对象都在堆中建立;

为了提高效率,线程会从堆中弄一个缓存到本身的栈;

在多线程状况下,从公共内存中读取变量存在线程不安全问题,使用volatile变量能够保证线程安全。

 

20. 什么是线程池?为何要使用它?

建立若干数量的线程来等待响应处理,就叫线程池,线程池里面的线程叫工做线程;

Java API提供了Execution框架能够建立不一样的线程池;

Why?

建立线程须要花费昂贵的资源和时间,任务来了在建立的话响应时间就会变长,影响效率;

能够建立单线程池,每次处理一个任务;

能够建立固定数量的线程池,或者可扩展的线程池来处理 多任务;

比喻:公交场

 

21. 如何解决生产者消费者问题?

一个线程生产任务,提供给其它线程进行消费 ,这就是属于生产者消费者模型;

生产者消费者问题,能够经过线程之间的通信来解决,java API提供了wait和notify方法来解决这个问题;

更好的方法是Semaphore或者BlockingQueue来实现生产者消费者模型。

 

22. 如何避免死锁?

死锁是两个或两个以上的进程在执行的时候,争夺资源形成相互等待,程序卡死的一种现象;

死锁的发生存在下面四个条件:

互斥条件,一个资源每次只能被一个进程调用;

请求与保持条件,一个进程得到资源阻塞时,对已经得到的资源保持不放;

不剥夺条件,进程已经得到资源,在未使用完成以前,不强行剥夺;

循环等待条件,进程之间头尾相接等待资源释放;

 

避免死锁就是阻止循环等待条件,将系统中的全部资源设置标志位,排序,规定全部的进程在申请资源的时候按顺序执行(升序或降序);

 

23. Java中活锁和死锁的区别?

活锁,就是进程的状态能够改变,可是不可以执行; 例如,走廊里两我的相遇,一个让一个,一直让不开的现象。

死锁,就是进程的状态不能改变,也不可以执行; 例如,走廊里两我的相遇,堵在那儿不动的现象。

 

24. 怎样检查一个线程是否拥有锁?

Java.lang.Thread中有一个方法holdsLock(),返回true,当前线程持有锁;

 

25. Java中synchronized和RentrantLock有什么不一样?

它们都是锁;

使用synchronized关键字做为锁来实现互斥,它能够锁方法,锁语句块,锁对象,可是不可以扩展锁以外的方法或者边界,尝试获取锁时候中途不能取消等;

Java5以后的lock接口提供了更为复杂的控制来解决并发问题;

RentrantLock类实现了Lock,它拥有synchronized相同的并发性和内存语义且扩展性更好。

 

26. 有3个线程,怎样保证他们按照顺序执行?

有不少种方法;

可使用join()方法在一个线程中启动另外一个线程,

好比:A,B,C三个线程;将A join到b中,b join到c中,先启动C线程,按照c-b-a的顺序执行;

 

27. Thread类中的yield方法有什么做用?

能够暂停当前正在执行的线程对象,让优先级高的先执行;

它是一个静态方法,保证当前线程放弃CPU占用,而不保证优先级高的就必定执行,有可能线程刚暂停又立马恢复;

 

28. Java中的ConcurrentHashMap的并发度是什么?

 ConcurrentHashMap把实际的map划分为若干部分来实现它的可扩展性和线程安全;

这种划分是使用并发度得到的,它是ConcurrentHashMap类构造函数的一个构造参数,默认值是16,这样能在多线程状况下避免争用。

 

29. 若是你提交任务时候,线程池已经满,会发生什么?

会抛异常RejectedExecutionException;由于在非扩展线程池的状况下该线程任务不可以被调度。

 

30. Java中线程池中的submit和execute方法有什么区别?

两个方法均可以向线程池提交任务;

execute方法的返回值类型是void,定义在Execotor接口中;

Submit方法返回持有计算结果的future对象,它定义在ExecutorService接口中,它扩展了Exector接口;

其它的线程池类ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些方法;

 

31. 什么是阻塞式方法?

指程序会等待该方法完成,期间不会作其它的事情;

ServerSocket类的accept方法就是阻塞式方法,会一直等待客户端链接;

阻塞指的是线程在调用结果返回以前,当前线程会被挂起,直到获得结果以后才会返回;

 

32. Java中的ReadWriteLock是什么?

读写锁,用来提高并发程序性能;

Java5 新增的接口,一个读写锁维护一对关联的锁,一个用于读操做,一个用于写操做;

读锁是共享的,写锁是独占的。

 

33. 多线程中的忙循环是什么?

忙循环就是开发者用空循环让一个线程等待,一直持有CPU的控制;

不像wait(),sleep(),yield()等方法,放弃了CPU的控制;

好处是保留CPU缓存,减小线程等待,避免重建缓存。

 

34. 若是同步块内的线程抛出异常会发生什么?

线程会释放锁;

 

35. 单例模式的双检锁是什么 ?

它是用来建立线程安全的,写单例模式的老方法;

当单例实例第一次被建立时候它试图用单个锁进行性能优化,可是因为太过复杂几乎没人用。

 

36. 如何在java中建立线程安全的singleton?

双检索实现单例;

也能够经过JVM的类加载和静态变量初始化特征来建立单例;

或者利用枚举实现;

以上三种都是线程安全的可用的;

 

37. 写出3条你遵循的多线程最佳实践?

1)给线程起一个有意义的名字

方便找bug或追踪线程执行;

2)避免锁定和缩小同步范围

锁花费的代价高昂,且上下文切换更耗费时间和空间,最低限度的使用同步锁,缩小临界区,有利于提高性能。

3)多用同步类,少用wait和notify

CountDownLatch, Semaphore, CyclicBarrier 和 Exchanger 等这些同步类简化了编码操做;

而wait和notify很难实现相对复杂控制流控制;

使用高级的同步工具备利于优化线程;

4)多用并发集合少用同步集合

并发集合比同步集合扩展性好

 

38. 如何强制启动一个线程?

线程是被线程 调度器控制的,java中没有提供响应的API。

 

39. Java多线程中调用wait和sleep的方法有什么不一样?

均可以让线程进入等待状态;

wait方法用于线程间通讯,若是等待条件为真且其它线程被唤醒是它会释放锁;

sleep方法仅仅是释放CPU的资源,让当前线程中止执行,不会释放锁;

 

 

 

  • 其它

1. CyclicBarrier 和 CountDownLatch有什么不一样?

CyclicBarrier和CountDownLatch均可以让一组线程等待其它线程;

不一样点是CountdownLatch不能从新使用。

 

2. 什么是FutureTask?

在java并发编程中,FutrueTask表示一个能够取消的异步运算;

它有启动运算,取消运算,查询运算,取回运算等方法,只有单运算完成才能取回结果,运算未完成get将会被阻塞。

异步运算也是调用Runnable接口,能够交给Executor来执行。

 

3. 为何应该在循环中检查等待条件?

处在等待状态的线程可能会收到错误报警和伪唤醒,不在循环中检查等待,程序就会在没有知足条件的状况下退出;

当一个线程被notify时候,并不认为它原来的状态仍然有效,由于这段时间它有可能改变。

 

4. 如何在java中获取线程堆栈?

JVM会把全部线程的状态存到日志文件,或者输出到控制台;

Windows中Ctrl+Break组合键获取;

Linux下用kill -3 命令获取;

业能够用jps这个工具找到id;

 

5. JVM中的那个参数是用来控制线程的栈堆大小的?

-Xss用来控制线程栈堆大小;

 

6. Java中的semaphore是什么?

是一种新的同步类,是一个计数信号;

信号量维护了一个许可集合,未经许可的线程请求会被阻塞,得到许可请求才能够进入排队状态;

Semaphore只对可用许可的信号进行计数;

信号量经常使用在多线程代码种,好比数据库链接池等

 

7. Swing是线程安全的么? 为何?

不是线程安全的;

由于swing的提供的组件不能再多线程中进行修改,全部对GUI组件的更新都须要在AWT线程中完成;

而swin提供了同步和异步两种回调方法来进行更新;

 

8. Java中的invokeAndWait和invokeLater方法有什么区别?

做用都是从当前线程更新GUI组件;

前者同步更新GUI组件,好比一个进度条,一旦更新了,进度条就要作出相应改变;

后者请求派线程更新组件,好比一个进度条,一旦更新,并无更新,须要等待派发线程完成更新,才最终更新。

 

9. Swing API中的哪些方法是线程安全的 ?

Swing不是线程安全的,它的一些方法是线程安全的;

好比:repaint(),revalidata(),JTextComponent的setText()方法和JTextArea的insert()方法和append()方法等。

 

10. Java中volatile变量和atomic变量有什么不一样?

Java中的volatile变量能够确保先行关系,写操做会发生在后续的读操做以前,可是并不能保证原子性;

例如用volatile修饰count变量,那么count++操做就不是原子性的;

AtomicInteger类提供的atomic方法可让这种操做具备原子性;

 

11. Java中的fork join框架是什么 ?

Fork join框架是JDK7出现的一款工具,java开发人员能够经过它,充分利用现代服务器上的多出来器;

能够将全部可用的处理能力调用起来提高程序性能;

它使用了工做窃取算法,能够完成更多任务的工做线程,能够从其它线程中窃取任务来执行。

相关文章
相关标签/搜索