`

匿名内部类及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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics