您的位置:首页 > 编程语言 > Java开发

JAVA多线程/并发问题与答案(1)

2018-03-20 22:46 183 查看

多线程

java中有几种方法可以实现一个线程?
JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。                                                                 参考地址:http://blog.csdn.net/aboy123/article/details/38307539

如何停止一个正在运行的线程?使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。(设一个boolean类型的标志)
使用interrupt方法中断线程,interrupt()方法的使用效果并不像for+break语句那样,马上就停止循环。调用interrupt方法是在当前线程中打了一个停止标志,并不是真的停止线程。

抛出异常,catch到抛出的异常,也能停止线程
使用return停止线程,将方法interrupt()与return结合使用也能实现停止线程的效果                                                                                                    参考博文:https://www.cnblogs.com/greta/p/5624839.html

notify()和notifyAll()有什么区别?                                                                                                                                                                              如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。                                                                           notify()方法,在等待池中 随机唤醒一个等待线程。notifyAll()是唤醒等待池中的所有线程,让他们   去竞争锁,得到锁的线程继续运行,未得到锁的线程,继续处于等待状态。                                                                                                                          
sleep()和 wait()有什么区别?                                                                                                                                                                                   1,这两个方法来自不同的类分别是Thread和Object
  2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
  3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在
    任何地方使用
   synchronized(x){
      x.notify()
     //或者wait()
   }
   4,sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常                                                                                                    参考文章:https://www.cnblogs.com/lancidie/archive/2011/01/24/1943401.html       
什么是Daemon线程?它有什么意义?                                                                                                                                                                    任何一个守护线程都是整个JVM中所有非守护线程的,只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。
Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一守护线程。                                    参考:http://blog.csdn.net/u010739551/article/details/51065923
java如何实现多线程之间的通讯和协作?                                                                                                                                                              1,共享内存,两个线程共同持有一个对象锁                                                                                                                                                        2,wait()/notify()/join()等方法                                                                                                                                                                              3,管道通信就是使用java.io.PipedInputStream 和 java.io.PipedOutputStream进行通信                                                                          4,Conditon的await()/signal()                                                                                                                                                                          参考:http://blog.csdn.net/justloveyou_/article/details/54929949

什么是可重入锁(ReentrantLock)?                                                                                                                                                                     锁的概念就不用多解释了,当某个线程A已经持有了一个锁,当线程B尝试进入被这个锁保护的代码段的时候.就会被阻塞.而锁的操作粒度是”线程”,而不是调用(至于为什么要这样,下面解释).同一个线程再次进入同步代码的时候.可以使用自己已经获取到的锁,这就是可重入锁java里面内置锁(synchronize)和Lock(ReentrantLock)都是可重入的                                                                                                 参考:http://blog.csdn.net/johnking123/article/details/50043961
当一个线程进入某个对象的一个synchronized的实例方法后,其它线程是否可进入此对象的其它方法?                                                               分几种情况:     1.其他方法前是否加了synchronized关键字,如果没加,则能。     2.如果这个方法内部调用了wait,则可以进入其他synchronized方法。     3.如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。参考:http://blog.csdn.net/bornlili/article/details/55803965         
synchronized和java.util.concurrent.locks.Lock的异同?                                                                                                                                        简要答案:   1.Lock能完成几乎所有synchronized的功能,并有一些后者不具备的功能,如锁投票、定时锁等候、可中断锁等候等   2.synchronized 是Java 语言层面的,是内置的关键字;Lock 则是JDK 5中出现的一个包,在使用时,synchronized 同步的代码块可以由JVM自动释放;Lock 需要程序员在finally块中手工释放,如果不释放,可能会引起难以预料的后果(在多线程环境中)。                                           参考:http://blog.csdn.net/hintcnuie/article/details/11022049
乐观锁和悲观锁的理解及如何实现,有哪些实现方式?                                                                                                                                           悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再比如Java里面的同步原语synchronized关键字的实现也是悲观锁。  乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。                                                                                                                                 参考:https://www.cnblogs.com/qjjazry/p/6581568.html

并发框架

SynchronizedMap和ConcurrentHashMap有什么区别?                                                                                                                                         SynchronizedMap类是定义在Collections中的一个静态内部类。它实现了Map接口,并对其中的每一个方法实现,通过synchronized关键字进行了同步控制。                                                                                                                                                                                               ConcurrentHashMap是java并发包下的一个并发集合框架,其用分段锁的方法保证线程安全。                                                           参考:https://www.cnblogs.com/grefr/p/6094888.html
CopyOnWriteArrayList可以用于什么应用场景?                                                                                                                                                    参考:http://blog.csdn.net/linsongbin1/article/details/54581787       

线程安全

什么叫线程安全?servlet是线程安全吗?
同步有几种实现方法?
volatile有什么用?能否用一句话说明下volatile的应用场景?
请说明下java的内存模型及其工作流程。
为什么代码会重排序?

并发容器和框架

如何让一段程序并发的执行,并最终汇总结果?
如何合理的配置java线程池?如CPU密集型的任务,基本线程池应该配置多大?IO密集型的任务,基本线程池应该配置多大?用有界队列好还是无界队列好?任务非常多的时候,使用什么阻塞队列能获取最好的吞吐量?
如何使用阻塞队列实现一个生产者和消费者模型?请写代码。
多读少写的场景应该使用哪个并发容器,为什么使用它?比如你做了一个搜索引擎,搜索引擎每次搜索前需要判断搜索关键词是否在黑名单里,黑名单每天更新一次。

Java中的锁

如何实现乐观锁(CAS)?如何避免ABA问题?
读写锁可以用于什么应用场景?
什么时候应该使用可重入锁?
什么场景下可以使用volatile替换synchronized?

并发工具

如何实现一个流控程序,用于控制请求的调用次数?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: