并发应用的一个最重要的方面是共享数据。
如果您创建一个实现 Runnable 接口的类对象并使用同一个 Runnable 对象启动不同的 Thread 对象,所有的线程共享同样的属性。 这意味着如果您在一个线程中改变一个属性,所有线程都将受此改变的影响。
有时您想有一个属性不在所有线程中共享。Java Concurrency API提供了一个名为thread-local变量的机制,简洁,性能也不错。
本节的示例代码在 com.elanzone.books.noteeg.chpt1.sect10 package中
线程类 : 不安全线程 (UnsafeTask)
private Date startDate;
startDate = new Date(); System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread().getId(), startDate); try { TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread().getId(), startDate);
线程类 : 安全线程 (SafeTask)
private static ThreadLocal<Date> startDate = new ThreadLocal<Date>() { protected Date initialValue() { return new Date(); } };
System.out.printf("Starting Thread: %s : %s\n", Thread.currentThread().getId(), startDate.get()); try { TimeUnit.SECONDS.sleep((int) Math.rint(Math.random() * 10)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.printf("Thread Finished: %s : %s\n", Thread.currentThread().getId(), startDate.get());
控制类 (Main)
UnsafeTask unsafeTask = new UnsafeTask(); for (int i = 0; i < 10; i++) { Thread thread = new Thread(unsafeTask); thread.start(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } }