标签:top 目的 ack 步骤 类库 无法 onexit 简化 修改
第66条:同步访问共享的可变数据
1 /** 2 * 共享原子可读写的变量不使用同步访问. 3 * Created by itlivemore on 17-7-1. 4 */ 5 public class StopThread { 6 private static boolean stopThread; 7 8 public static void main(String[] args) throws InterruptedException { 9 Thread backGroundThread = new Thread(new Runnable() { 10 @Override 11 public void run() { 12 int i = 0; 13 while (!stopThread) { 14 System.out.println("i = " + i++); 15 } 16 } 17 }); 18 backGroundThread.start(); 19 20 TimeUnit.SECONDS.sleep(1); 21 stopThread = true; 22 } 23 }
书上写道这个程序不会停止,但是我在自己的机器上运行1秒后停止了。作者的解释是JVM对代码优化了。
while(!done) { i++; }
优化成了
if(!done) { while(true) { i++; } }
修正方法:
1 ** 2 * 没有正确使用同步导致安全性失败 3 * Created by itlivemore on 17-7-1. 4 */ 5 public class SafetyFailure { 6 private static volatile int nextSerialNumber = 0; 7 8 /*生成唯一的序列号的方法。nextSerialNumber虽然声明为volatile,但是++操作不是原子性的,需要两个步骤: 9 * 先读取值,然后再写入值。如果线程读取值之后被阻塞,另一个线程也读取值,将会导致两个线程读取的值一样*/ 10 public static int generateSerialNumber() { 11 return nextSerialNumber++; 12 } 13 14 /*修正方法一:增加synchronized来同步*/ 15 public synchronized static int generateSerialNumber2() { 16 return nextSerialNumber++; 17 } 18 19 /*修正方法二:使用AtomicLong*/ 20 private static final AtomicLong nextSeriaNumber2 = new AtomicLong(); 21 22 public static long generateSerialNumber3() { 23 return nextSeriaNumber2.getAndIncrement(); 24 } 25 }
第67条:避免过度同步
1 /** 2 * 同步区域中调用外来方法 3 * Created by itlivemore on 17-7-1. 4 */ 5 class Other { 6 public static void remove(List<Integer> list, int i) { 7 if (i == 2) { 8 list.remove(new Integer(i)); 9 } else { 10 System.out.println(i); 11 } 12 } 13 } 14 15 public class SynchronizedCall { 16 17 static List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9)); 18 19 public static void foreachlist() { 20 synchronized (list) { 21 int i = 0; 22 for (Integer integer : list) { 23 Other.remove(list, i++); 24 } 25 } 26 } 27 28 public static void main(String[] args) { 29 //会有异常,因为遍历时删除 30 foreachlist(); 31 }
第68条:executors和task优先于线程
1 /** 2 * ExecutorService的简单使用 3 * Created by itlivemore on 17-7-1. 4 */ 5 public class Executor { 6 public static void main(String[] args) { 7 // 创建 8 ExecutorService executorService = Executors.newSingleThreadExecutor(); 9 // 执行任务 10 executorService.execute(new Runnable() { 11 @Override 12 public void run() { 13 System.out.println(System.currentTimeMillis()); 14 } 15 }); 16 // 关闭 17 executorService.shutdown(); 18 } 19 }
第69条:并发工具优先于wait和notify
1 /** 2 * String.intern()方法 3 * Created by itlivemore on 17-7-1. 4 */ 5 public class StringIntern { 6 public static void main(String[] args) { 7 String str1 = "abc"; 8 String str2 = new String("abc"); 9 // 返回true,说明是同一对象 10 System.out.println(str1 == str1.intern()); 11 // 返回的是false 12 System.out.println(str1 == str2); 13 } 14 }
String.intern()的参考:http://blog.csdn.net/hanrentanfei/article/details/1817402
// 使用wait方法的标准模式 synchronized(ojb) { while(condition) { obj.wait(); } }
第69条:线程安全性的文档化
// 私有锁对象,防止拒绝服务攻击 private final Object lock = new Object(); public void foo() { synchronized(lock) {} }
第69条:慎用延迟初始化
1 /** 2 * 延迟初始化的几种方式 3 * Created by itlivemore on 17-7-1. 4 */ 5 public class LazyInitialzation { 6 /*同步访问方法的延迟初始化*/ 7 private Integer field1; 8 9 synchronized Integer getField1() { 10 if (field1 == null) { 11 field1 = 1; 12 } 13 return field1; 14 } 15 16 /*出于性能考虑对静态域使用延迟初始化*/ 17 private static class FieldHolder { 18 static final Integer field = 2; 19 } 20 21 static Integer getField2() { 22 return FieldHolder.field; 23 } 24 25 26 /*出于性能考虑对实例域使用延迟初始化,就使用双重检查模式*/ 27 private volatile Integer field3; // 注意这里要声明为volatile 28 29 Integer getField3() { 30 // 增加局部变量result是确保field只在已经被初始化的情况下读取一次 31 Integer result = field3; 32 if (result == null) { 33 synchronized (this) { 34 result = field3; 35 if (result == null) { 36 field3 = result = 3; 37 } 38 } 39 } 40 return result; 41 } 42 43 /*延迟初始化一个接受重复初始化的实例域,使用单重检查模式*/ 44 private volatile Integer field4; 45 46 Integer getField4() { 47 Integer result = field4; 48 if (result == null) { 49 field4 = result = 4; 50 } 51 return result; 52 } 53 }
第69条:不要依赖于线程调度器
第70条:避免使用线程组
标签:top 目的 ack 步骤 类库 无法 onexit 简化 修改
原文地址:http://www.cnblogs.com/lgc13136/p/7103414.html