线程安全问题可以用银行转账来解释
1 /** 2 * 传统的线程互斥技术 3 * @author LiTaiQing 4 */ 5 public class TraditionalThreadSynchronized { 6 7 public static void main(String[] args){ 8 new TraditionalThreadSynchronized().init(); 9 } 10 11 private void init(){ 12 /** 13 * 内部类访问局部变量,局部变量要加final 14 * 若此代码放在main中会报错,因为静态代码块不能访问内部类 15 */ 16 final Outputer outputer = new Outputer(); 17 new Thread(new Runnable(){ 18 @Override 19 public void run() { 20 while(true){ 21 try { 22 Thread.sleep(1000); 23 } catch (InterruptedException e) { 24 e.printStackTrace(); 25 } 26 outputer.output("zhangxiaoxiang"); 27 } 28 } 29 }).start(); 30 new Thread(new Runnable(){ 31 @Override 32 public void run() { 33 while(true){ 34 try { 35 Thread.sleep(1000); 36 } catch (InterruptedException e) { 37 e.printStackTrace(); 38 } 39 outputer.output("lihuoming"); 40 } 41 } 42 }).start(); 43 } 44 45 static class Outputer{ 46 public void output(String name){ 47 int len = name.length(); 48 /* 49 * 锁用任意一个对象都行,但只有同一个对象才具有互斥性 50 * 1.每个类的字节码文件只有一份,可以用来做互斥锁 51 * 2.用this也行 52 * 此处也可以在方法上架synchroized, 53 * 但从多线程效率角度来看,合理细化同步块粒度能提高执行效率, 54 * 所以此处在内部代码中加synchroized比较好 55 */ 56 synchronized(Outputer.class){ 57 for(int i = 0; i < len ; i++){ 58 System.out.print(name.charAt(i)); 59 } 60 System.out.println(); 61 } 62 } 63 /** 64 * output2方法不会同步,因为方法上加synchronized相当于加this锁 65 * 但又是静态方法,所以this会失效,会出现问题。 66 * @param name 67 */ 68 public static synchronized void output2(String name){ 69 int len = name.length(); 70 synchronized(Outputer.class){ 71 for(int i = 0; i < len ; i++){ 72 System.out.print(name.charAt(i)); 73 } 74 System.out.println(); 75 } 76 } 77 } 78 }