牛客错题总结--线程(一)

简介: 牛客错题总结--线程(一)

1.java运行时内存分为“线程共享”和“线程私有”两部分,以下哪些属于“线程共享”部分


答:私有:java虚拟机栈和本地方法栈  ,程序计数器   共享:java堆,方法区


2.假如某个JAVA进程的JVM参数配置如下:

-Xms1G -Xmx2G -Xmn500M -XX:MaxPermSize=64M -XX:+UseConcMarkSweepGC -XX:SurvivorRatio=3,

请问eden区最终分配的大小是多少?

答:300M


Xms 起始内存,Xmx 最大内存,Xmn 新生代内存,Xss 栈大小。 就是创建线程后,分配给每一个线程的内存大小


-XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4


-XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5


-XX:MaxPermSize=n:设置持久代大小


收集器设置

-XX:+UseSerialGC:设置串行收集器

-XX:+UseParallelGC:设置并行收集器

-XX:+UseParalledlOldGC:设置并行年老代收集器

-XX:+UseConcMarkSweepGC:设置并发收集器

垃圾回收统计信息

-XX:+PrintGC

-XX:+PrintGCDetails

-XX:+PrintGCTimeStamps

-Xloggc:filename

并行收集器设置

-XX:ParallelGCThreads=n:设置并行收集器收集时使用的CPU数。并行收集线程数。

-XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间

-XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

并发收集器设置

-XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。

-XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。(摘自:牛友)


3.以下各类中哪几个是线程安全的?


答:喂(Vector),S(Stack),H(hashtable),E(enumeration)


4.下面哪些具体实现类可以用于存储键,值对,并且方法调用提供了基本的多线程安全支持:


答:线程安全的map:HashTable,SynchronizedMap,ConcurrentHashMap,Hashtable的方法都是synchrnized修饰的线程安全。


解析:(摘自:牛友:雷布斯克茨威格)


Hashtable是线程安全的哈希表,它是通过synchronized来保证线程安全的;即,多线程通过同一个“对象的同步锁”来实现并发控制。Hashtable在线程竞争激烈时,效率比较低(此时建议使用ConcurrentHashMap)。当一个线程访问Hashtable的同步方法时,其它线程如果也在访问Hashtable的同步方法时,可能会进入阻塞状态。

Collections.synchronizedMap()使用了synchronized同步关键字来保证对Map的操作是线程安全的。

ConcurrentHashMap是线程安全的哈希表。在JDK1.7中它是通过“锁分段”来保证线程安全的,本质上也是一个“可重入的互斥锁”(ReentrantLock)。多线程对同一个片段的访问,是互斥的;但是,对于不同片段的访问,却是可以同步进行的。在JDK1.8中是通过使用CAS原子更新、volatile关键字、synchronized可重入锁实现的。

5.以下哪种方式实现的单例是线程安全的


答:枚举、静态内部类、双检锁模式、饿汉式

6.假设 a 是一个由线程 1 和线程 2 共享的初始值为 0 的全局变量,则线程 1 和线程 2 同时执行下面的代码,最终 a 的结果不可能是

boolean isOdd = false;
for(int i=1;i<=2;++i){
    if(i%2==1)isOdd = true;
    else isOdd = false;
    a+=i*(isOdd?1:-1);
}


答:1



7.Java的Daemon线程,setDaemon( )设置必须要?

答:在start之前


解析:(摘自;牛友:打不倒的小迷糊)


java线程是一个运用很广泛的重点知识,我们很有必要了解java的daemon线程.


1.首先我们必须清楚的认识到java的线程分为两类: 用户线程和daemon线程


A.  用户线程: 用户线程可以简单的理解为用户定义的线程,当然包括main线程(以前我错误的认为main线程也是一个daemon线程,但是慢慢的发现原来main线程不是,因为如果我再main线程中创建一个用户线程,并且打出日志,我们会发现这样一个问题,main线程运行结束了,但是我们的线程任然在运行).


B.  daemon线程: daemon线程是为我们创建的用户线程提供服务的线程,比如说jvm的GC等等,这样的线程有一个非常明显的特征: 当用户线程运行结束的时候,daemon线程将会自动退出.(由此我们可以推出下面关于daemon线程的几条基本特点)


2. daemon 线程的特点:


A.  守护线程创建的过程中需要先调用setDaemon方法进行设置,然后再启动线程.否则会报出IllegalThreadStateException异常.(个人在想一个问题,为什么不能动态更改线程为daemon线程?有时间一个补上这个内容,现在给出一个猜测: 是因为jvm判断线程状态的时候,如果当前只存在一个线程Thread1,如果我们把这个线程动态更改为daemon线程,jvm会认为当前已经不存在用户线程而退出,稍后将会给出正确结论,抱歉!如果有哪位大牛看到,希望给出指点,谢谢!)


B.  由于daemon线程的终止条件是当前是否存在用户线程,所以我们不能指派daemon线程来进行一些业务操作,而只能服务用户线程.


C.  daemon线程创建的子线程任然是daemon线程.


相关文章
|
安全 Java 调度
金三银四面试题--多线程(一)
金三银四面试题--多线程
67 0
|
7月前
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
【一刷《剑指Offer》】面试题 23:从上往下打印二叉树
|
7月前
|
编译器 C++ 容器
刷题日记② --- 选择题
刷题日记② --- 选择题
64 1
|
Cloud Native
【刷题日记】641. 设计循环双端队列
【刷题日记】641. 设计循环双端队列
|
C语言
LeetCode刷题集(二)(LeetCode 2037使每位学生都有座位的最少移动次数)
LeetCode刷题集(二)(LeetCode 2037使每位学生都有座位的最少移动次数)
64 0
C/C++ leetcode刷题的各种小tips记录
C/C++ leetcode刷题的各种小tips记录
139 0
|
监控 算法
牛客刷题记录(常见笔试题)(下)
牛客刷题记录(常见笔试题)(下)
125 0
牛客刷题记录(常见笔试题)(上)
牛客刷题记录(常见笔试题)(上)
111 0
|
移动开发 前端开发 JavaScript