`
king_tt
  • 浏览: 2154643 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

关于ThreadLocal的一道面试题(酷我公司)

 
阅读更多

2013年8月,本人那时候刚毕业来到了北京找工作,在网上投递了各种简历,也面试了很多家公司,遇到最大的问题就是:你什么时候毕业的呀?,做过什么项目呀?都将我拒之门外,但是我还是幸运总会来的,那天早上9点半的时候,接到电话,说叫我去面试,问了一下是什么公司?是酷我,感觉公司规模挺大的还可以,就很兴奋的跑去面试了,他们公司没有笔试,只有面试,有三轮面试,第一轮就是问你做过哪些项目,都遇到什么问题怎么解决的等,和技术不沾边,第二轮面试的时候就来了一个技术,问了很多关于技术上的问题,但是貌似都不深入,比如:怎样快速的查找到单链表中的倒数第k个元素(网上有答案,上数据结构课的时候老师说过的);找出两个升序序列的相同元素(普通方法肯定是可以的,但是不是他想要的答案,使用头指针和尾指针,时间复杂度是O(n));单列表的反转等这些问题。因为我是有准备去面试的,这些问题网上很是流传,所以早弄得滚瓜烂熟了,全部搞定,感觉他挺满意的,最后他又来一道题:


单例模式的定义?单例模式有哪些形式?怎样控制多线程访问单例模式?怎么提高多线程访问单例模式的性能?

其实总共是四个问题,都是循序渐进的:个人感觉这个问题我没有准备,但是我之前搞过这些:所以就开始回答了:


1.单例模式的定义很简单的:构造方法为private,定义一个static的自身实例变量,提供一个static的供外部访问对象的getInstance方法


2.单例模式有懒汉和饿汉模式:具体看下面的代码:

//比较:
//饿汉式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变
//懒汉式如果在创建实例对象时不加上synchronized则会导致对对象的访问不是线程安全的,因为多个线程可能创建出多个实例
//推荐使用第一种 

//饿汉式:
class HungrySingleton{
    private static HungrySingleton hungrysingleton = new HungrySingleton();
    private HungrySingleton (){}
    public HungrySingleton getInstance(){
    	return hungrysingleton;
    }
} 

//懒汉式:
class FullSingleton{
    private static FullSingleton fullsingleton = null;
    public static synchronized FullSingleton getInstance(){
         if(fullsingleton==null){
        	 fullsingleton = new FullSingleton();
         }
        return fullsingleton;
    }
} 

3.我们看一下上面的代码:

对于饿汉模式是不存在多线程访问不安全的问题的,只有下面的懒汉模式有多线程访问的安全问题,所以我们在getInstance()方法前加入synchronized进行互斥操作即可


4.因为我们知道使用synchronized关键字来实现互斥,性能很低的,所以怎么提高性能呢?有的人可能说了,直接使用饿汉模式就可以了,但是现在我们就是用懒汉模式来实现,多线程访问,那就可以想到了Java中的ThreadLocal类了,就是和本线程相关的一个map集合,这样就很好理解了,但是他内部实现是很复杂的,要考虑到效率的问题,比如一个线程消亡的时候,线程持有的资源该怎么释放都是要特殊处理的,但是我们没必要考虑他那么深入,只要知道怎么用的就行了,下面就直接来看一下代码吧:

package cn.itcast.heima;

import java.util.Random;

public class ThreadLocalTest {
	
	public static void main(String[] args){
		//开启两个线程设置值
		for(int i=0;i<2;i++){
			new Thread(new Runnable(){
				@Override
				public void run() {
					int data = new Random().nextInt();
					System.out.println(Thread.currentThread().getName()+" has put data :" + data);
					MyThreadScopeData.getInstance().setName(data+"");
					MyThreadScopeData.getInstance().setAge(data+"");
					new A().get();
					new B().get();
				}
				
			}).start();
		}
	}
	
	//获取值
	static class A{
		public void get(){
			System.out.println(Thread.currentThread().getName()+" : " + "Name:"+MyThreadScopeData.getInstance().getName());
			System.out.println(Thread.currentThread().getName()+" : " + "Age:"+MyThreadScopeData.getInstance().getAge());
		}
	}
	
	//获取值
	static class B{
		public void get(){
			System.out.println(Thread.currentThread().getName()+" : " + "Name:"+MyThreadScopeData.getInstance().getName());
			System.out.println(Thread.currentThread().getName()+" : " + "Age:"+MyThreadScopeData.getInstance().getAge());
		}
	}

}

class MyThreadScopeData{
	
	private MyThreadScopeData(){}
	
	private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();
	//因为使用了ThreadLocal的方法,所以这里就不需要synchronized,这样效率就更高了
	public static MyThreadScopeData getInstance(){
		MyThreadScopeData instance = map.get();
		if(instance == null){
			instance = new MyThreadScopeData();
			map.set(instance);
		}
		return instance;
	}
	
	private String name;
	private String age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	
	
}
代码中定义了两个线程,我们在MyThreadScopeData类中的getInstance()方法中我们使用到了ThreadLocal类,将对象实例和线程相关联上,运行结果:



我们从结果可以看到,两个线程产生的数据是一致的。这样四个问题就回答完了,其实我现在也不清楚这几个问题回答的怎么样,但是面试很顺利,所以我就分享一下我的答案!如有不正确的地方,希望给予指正,小弟不胜感激。

分享到:
评论

相关推荐

    有关ThreadLocal的面试题你真的懂了吗

    "ThreadLocal相关知识点总结" ThreadLocal是Java中的一种机制,用于在多线程环境中保存线程上下文信息,并且提供了一种解决多线程程序并发问题的思路。下面是对ThreadLocal的主要知识点的总结: 1. ThreadLocal的...

    面试题得物1

    【面试题得物1】涉及了众多IT领域的知识点,涵盖了Java、Kafka、RocketMQ、MySQL、Redis、算法和分布式等多个方面。以下是这些知识点的详细解释: 1. **数据库索引结构**:索引是数据库管理系统中用于提高查询速度...

    多线程面试题

    本文将围绕“多线程面试题”这一主题,深入探讨相关概念、技术及其应用。 1. **线程的概念**:线程是程序执行的最小单位,一个进程可以有多个线程同时执行任务,提高了程序的运行效率。 2. **Java中的线程创建方式...

    2021最新Java面试题合集.zip

    Java作为一门广泛使用的编程语言,其面试题涵盖了众多领域,包括基础、并发编程、网络、虚拟机、大数据处理以及各种框架。以下是对这些面试题集合的详细解析: 1. **BIO, NIO, AIO, Netty面试题 35道**: - **BIO*...

    java面试题以及技巧

    │ 上海税友软件 面试题.doc │ 公司培训文档-混淆的基本概念.doc │ 基本算法.doc │ 孙卫琴精通struts.基于MVC的.java.web设计与开发.pdf │ 学习Struts提供的和Form相关标签.txt │ 日企编码规范.doc │ 电信盈科...

    面试题全集(周瑜).pdf

    * ThreadLocal的底层原理 * 并发、并行、串行之间的区别 * Java死锁如何避免? * 线程池的底层工作原理 * ReentrantLock中的公平锁和非公平锁的底层实现 * CountDownLatch和Semaphore的区别和底层原理 四、Java异常...

    java面试宝典-经典面试题及java编程基础

    《Java面试宝典-经典面试题及Java编程基础》是一本汇集了大量Java面试题和基础知识的宝贵资源,旨在帮助Java开发者在求职面试过程中更好地准备和提升自我。这本书的内容广泛,涵盖了从基础概念到高级技术的多个领域...

    ThreadLocal应用示例及理解

    以上就是关于ThreadLocal的基本概念、使用方法、生命周期管理和实际应用示例的详细解释。了解并熟练掌握ThreadLocal可以帮助我们编写出更高效、更安全的多线程代码。在Java并发编程中,ThreadLocal是一个不可或缺的...

    java面试题汇总2017版

    Java作为一门广泛使用的编程语言,其面试题涵盖了众多领域,包括基础语法、面向对象、集合框架、多线程、异常处理、JVM内存模型、IO流、网络编程、设计模式、数据库操作、Spring框架等。这份2017版的Java面试题汇总...

    从面试中的问题分析ThreadLocal

    "ThreadLocal知识点详解" ThreadLocal是一个本地线程副本变量工具类,主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个...

    JAVA面试题大全,祝您面试顺利

    Java面试题大全旨在帮助求职者全面准备Java相关的技术面试,涵盖了多个关键领域。这份资源包含了以下主要内容: 1. **Java基础知识面试题(2020最新版)**:这部分主要测试求职者的Java语言基础,包括但不限于语法...

    2019蚂蚁金服面试题及答案

    Java 面试题知识点总结 本文将对 Java 相关的面试题进行总结,涵盖 Java 基础、多线程、线程池、JVM、数据库、Spring、SpringMVC、MyBatis 等知识点。 一、Java 基础 1. 字符串常量池:JVM 为了提高性能和减少...

    2021年Java大厂面试题整理大全

    "2021年Java大厂面试题整理大全"是一个集合了众多Java专业面试问题的资源,旨在帮助求职者准备Java相关的职位面试。这个压缩包可能包含了大量的面试题目、解答以及一些关键知识点的总结,涵盖从基础到高级的各个方面...

    1000道 互联网大厂Java工程师面试题及其答案.rar

    本资源“1000道 互联网大厂Java工程师面试题及其答案.rar”显然是一个针对Java工程师面试准备的综合资料包,包含了丰富的面试问题和对应的解答,旨在帮助求职者提升面试成功率。 首先,我们要明白Java工程师面试...

    ThreadLocal

    ThreadLocal是Java编程语言中的一个类,用于在多线程环境中提供线程局部变量。它是一种特殊类型的变量,每个线程都有自己的副本,互不影响,从而实现线程间数据隔离。ThreadLocal通常被用来解决线程共享数据时可能...

    笔试面试题国内知名公司

    这份"笔试面试题国内知名公司"的压缩包文件包含了丰富的资源,专为准备Java面试的人士提供。以下将根据提供的文件名,解析出其中可能涵盖的Java知识点。 1. **Java基础** - `java面试题[基础类].txt` 和 `java面试...

    Java常见面试题208道.docx

    面试题包括以下十九部分:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql...

    2017年最新最全java面试题集锦

    本资源"2017年最新最全Java面试题集锦"正是为此目的而设计,它包含了丰富的Java面试题目,帮助求职者在面试中展现自己的技术实力。 面试题集主要覆盖以下几个关键知识点: 1. **基础语法**:包括变量、数据类型、...

    2023年Java面试题+详细总结.docx

    Java 面试题总结 ThreadLocal ThreadLocal 是 Java 中的一种线程变量副本机制,它为每个线程维护一个本地变量。 ThreadLocal 采用空间换时间,用于线程间的数据隔离,为每一个使用该变量的线程提供一个副本,每个...

Global site tag (gtag.js) - Google Analytics