`

匿名内部类及Threadlocal 类的使用

    博客分类:
  • java
阅读更多

一、java的匿名内部类

在编程过程中如果遇到类的内部需要继承某个父类实现重写该父类的某些方法,而其他地方用得少,就可以直接在类的内部创建继承父类或者实现接口的实例,供程序使用。

import java.util.concurrent.TimeUnit;

/**
 *匿名内部类的使用
 * @author  Walter.Huang
 * @create date 2014-12-9
 */
public class Memo {
	public static void main(String[] args) {
        
		Person man=new Person(){//匿名内部类
			@Override
			public void eat() {
				System.out.println("eat bitter");
			}
        };
        man.eat();
        
        
        Runnable runner =new Runnable(){//实现接口的匿名内部类
			@Override
			public void run() {
				System.out.println("start working!");
				System.out.println("working...");
				try {
					TimeUnit.SECONDS.sleep(3);
				} catch (InterruptedException e) {
				}
				System.out.println("finished!");
			}
        	
        };
        new Thread(runner).start();
        
    }
}


abstract class Person {
    public abstract void eat();
}

 

二、关于ThreadLocal类的使用

ThreadLocal 类提供了一个机制可以防止多线程访问带来的不安全机制。实际上就是在线程本地保存一个变量,而不是通过共享变量。这个就要看我们的使用场合了,如果我们确实需要共享的数据,那还是必须通过同步机制来保证数据的安全。如果有些情况希望不同的线程保存的变量各自分开,那用这个还是比较合适的。

ThreadLocal 这个类本身不是代表线程要访问的变量,这个类的成员变才是。 

JDK1.5 给 ThreadLocal 加了泛型功能,即是 ThreadLocal<T>, 这个泛型 T 即是要线程的本地变量。线程通过 ThreadLocal  get  set 方法去访问这个变量 T  ThreadLocal 提供了一个机制,它能保证线程通过这个来访问它来访问类型为 T 的变量的时候是不同的拷贝。所以访问该变量必须通过 Threadlocal 这个类只提供了两个 public 方法,即是 get()  set()方法来访问。

同时还提供了一个 inintValue()  protected 方法。该方法用来初始化变量值。

注意 :默认情况下 initValue(), 返回 null 。线程在没有调用 set 之前,第一次调用 get 的时候, get方法会默认去调用 initValue 这个方法。所以如果没有覆写这个方法,可能导致 get 返回的是 null 。当然如果调用过 set 就不会有这种情况了。但是往往在多线程情况下我们不能保证每个线程的在调用 get 之前都调用了set ,所以最好对 initValue 进行覆写,以免导致空指针异常。

 

实例:

/**
 * 不使用ThreadLocal
 * @author  Walter.Huang
 * @create date 2014-12-9
 */
public class NoneLocalClass {
	
	public static int a = 0;//共享常量
	public static int MAX = 100;//共享常量
		
	public static class NoneLocalThread extends Thread {
		public void run() {//常量的值
			for ( int i = 0; i < MAX; i++) {
				a = a + 1;
				System. out .println(Thread. currentThread ().getName() + ":" + a );
			}
		}
	}
	
	public static void main(String[] args) {
		NoneLocalThread thread = new NoneLocalThread();
		thread.start();
		
		for ( int i = 0; i < MAX; i++) {//主线程
			a = a + 1;
			System. out .println(Thread. currentThread ().getName() + ":" + a );
		}
	}

}

 

 

 

 

结果会出现:

Thread-0:2

Thread-0:3

Thread-0:4

Thread-0:5

main:2

Thread-0:6

 

main:7

       ……

 

 

/**
 * 使用ThreadLocal
 * @author Walter.Huang
 * @create date 2014-12-9
 */
public class LocalClass {
	private static ThreadLocal<Integer> a = new ThreadLocal<Integer>() {
		public Integer initialValue() { // 初始化,默认是返回 0
			return 0;
		}
	};

	public static class LocalThread extends Thread {
		public void run() {
			for (int i = 0; i < 5; i++) {
				a.set(a.get() + 1);
				System.out.println(Thread.currentThread().getName() + ":"
						+ a.get());
			}
		}
	}

	public static void main(String args[]) {
		LocalThread thread = new LocalThread();
		thread.start();

		for (int i = 0; i < 5; i++) {
			a.set(a.get() + 1);
			System.out.println(Thread.currentThread().getName() + ":" + a.get());
		}
	}
}

 

输出结果:

main:1

main:2

main:3

main:4

main:5

Thread-0:1

Thread-0:2

Thread-0:3

Thread-0:4

Thread-0:5

 

分享到:
评论

相关推荐

    ThreadLocal内存泄露分析

    2. **匿名内部类与ThreadLocal的结合**:在匿名内部类中使用ThreadLocal,由于内部类会隐式持有对外部类的引用,如果外部类对象很大,且线程持续存在,那么这个大的外部类对象也无法被垃圾收集,从而引发内存泄露。...

    ThreadLocal源码分析和使用

    //通过匿名内部类覆盖 ThreadLocal 的 initialValue()方法,指定初始值 private static ThreadLocal&lt;Integer&gt; seNum=new ThreadLocal(){ protected Integer initialValue(){ return 0; } } public Integer ...

    详细介绍java中的内部类共8页.pdf.zip

    3. 匿名内部类:没有名字的内部类,通常用于创建一次性使用的类,常用于实现接口或继承类。 4. 静态内部类:类似于普通的静态成员,不持有对外部类的引用,可以直接通过外部类名访问。 二、内部类的特点与用途: 1....

    thinkingInJava10:内部类

    匿名内部类没有名称,通常用于快速实现一个接口或者继承一个类的简单版本。它们常用于事件处理,比如GUI编程中的按钮点击事件。 4. **静态内部类** 静态内部类与普通的成员内部类不同,它们不持有对外部类的引用...

    Java并发编实践之ThreadLocal变量.doc

    默认实现返回`null`,如果需要初始化为非`null`的值,需要创建ThreadLocal的子类并重写此方法,通常会用到匿名内部类来实现。 2. `public T get()`: 这个方法获取当前线程副本中的变量值。如果当前线程还没有分配值...

    JAVA程序员面试32问.非常经典的java面试题库

    - 匿名内部类没有名字,不能继承其他类,但可以实现接口。 3. **Static Nested Class 和 Inner Class的不同** - Static Nested Class(静态内部类):可以独立于外部类实例存在,创建时不需依赖外部类的实例,且...

    Thinking in Java, 2nd edition

    - 包括匿名内部类、成员内部类、局部内部类和静态内部类,它们提供了一种更灵活的封装方式。 6. 泛型: - Java 5引入的泛型增强了类型安全,避免了类型转换的麻烦。 7. 集合框架: - ArrayList、LinkedList、...

    java面试题

    - 内部类:了解匿名内部类、成员内部类和局部内部类。 - 异常处理:理解异常分类,何时使用try-catch-finally,以及如何自定义异常。 2. **集合框架**: - List、Set、Map接口及其实现类的区别:如ArrayList、...

    thinking in java (第三版)

    内部类包括成员内部类、局部内部类、匿名内部类,它们在处理复杂问题时非常有用。 4. **异常处理**:Java的异常处理机制是程序健壮性的重要保障,书中会介绍如何使用try-catch-finally语句块,以及如何自定义异常。...

    Context的理解1

    - 非静态内部类(包括匿名内部类)会持有外部类引用,导致外部类无法释放。解决方案是使用静态内部类,并对传递的外部类引用使用弱引用,且需做null检查。 - 忘记关闭资源,如File、Stream、Bitmap、...

    疯狂JAVA讲义

    6.7.5 匿名内部类 212 6.7.6 闭包(Closure)和回调 215 6.8 枚举类 217 6.8.1 手动实现枚举类 217 6.8.2 枚举类入门 219 6.8.3 枚举类的属性、方法和构造器 220 6.8.4 实现接口的枚举类 223 6.8.5 包含抽象...

    jdk api 1.8_China.zip

    2. **方法引用来代替匿名内部类**:在某些场景下,可以使用方法引用替代Lambda表达式,如`Runnable`接口的实现。 3. **默认方法**:接口中可以定义带有实现的方法,增强了接口的功能,使得接口在不破坏向后兼容性的...

    后端开发-06-线程执行带有参数的任务.ev4.rar

    - **匿名内部类传参**:使用匿名内部类实现Runnable接口时,可以将参数作为局部变量引入,然后在线程的run()方法中使用。 - **线程局部变量**:Java的ThreadLocal类可以为每个线程提供独立的副本,用于存储和传递...

    内螺纹

    内部类分为成员内部类、局部内部类、匿名内部类和静态内部类。在上下文中,我们可能讨论的是静态内部类,因为它能被实例化而无需外部类对象,更适合用来创建线程。 静态内部类创建的线程示例: ```java public ...

    Thinking in Java

    4. **接口与内部类**:详细解析了接口的作用,以及如何使用内部类(包括匿名内部类)来实现复杂的抽象。 5. **多线程**:讲解了Java中的并发编程,包括线程的创建、同步机制(如synchronized关键字、wait()和notify...

    高级软件工程师面试题.pdf

    - Lambda表达式:提供一种简洁的表示匿名内部类的方法。 - Stream API:对集合进行过滤、映射、排序等操作的高级抽象。 - 时间日期API:Java 8引入了新的时间日期API,如LocalDate、LocalTime等。 由于文件内容...

    自己整理的JAVA试题

    【JAVA笔试面试知识点详解】 1. **数据库查询优化** - **最大年龄用户查询**: 这种查询可以通过在`User`表的`age... - **内部类**可以是成员内部类、局部内部类、匿名内部类或静态内部类,提供封装和代码组织的功能。

    JAVA核心技术第八版源代码

    11. **Lambda表达式与函数式编程**:Java 8引入的特性,简化匿名内部类,函数接口,Stream API。 12. **模块化系统**:Java 9引入的模块化系统,模块化构建,模块间的依赖管理。 13. **JVM内存模型**:堆内存、栈...

    Java面经.适用于校招

    - 匿名类是创建在方法内部的没有名称的类。 1.41.2 匿名类 - 匿名类是即时创建并且没有类名的类实例。 二.集合类Set Java集合框架提供了用于存储和操作数据的接口和类。 2.1 HashMap - HashMap是基于哈希表的Map...

    Android常见原理性面试专题.pdf

    - 避免静态内部类或匿名内部类持有Activity引用。 - 使用WeakReference或软引用(SoftReference)包裹可能引发内存泄漏的对象。 - 在不再使用时,及时断开对Context、View、BroadcastReceiver等的引用。 - 注意...

Global site tag (gtag.js) - Google Analytics