当多个线程同时读写一个对象的数据时就可能产生竞争,java提供了几种方法防止竞争。
1.synchronized方法。当一个对象调用某个synchronized方法时,若其他线程也想调用该对象的synchronized方法时,则会阻塞。
2.Lock对象。
3.synchronized子句。
1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 import java.util.concurrent.TimeUnit; 4 import java.util.concurrent.locks.Lock; 5 import java.util.concurrent.locks.ReentrantLock; 6 7 8 public class SynchronizedTest { 9 10 static class Run implements Runnable 11 { 12 private IncreaseThree it; 13 private int times; 14 15 public Run(IncreaseThree it, int times) 16 { 17 this.it = it; 18 this.times = times; 19 } 20 21 @Override 22 public void run() { 23 for (int i = 0; i < times; i++) 24 { 25 it.increaseThree(); 26 } 27 } 28 29 } 30 31 public static void main(String[] args) throws InterruptedException 32 { 33 IncreaseThree it = new IncreaseThree(); 34 //it = new SynchronizedIncrease1(); 35 //it = new SynchronizedIncrease2(); 36 //it = new LockIncreaseThree(); 37 38 ExecutorService es = Executors.newCachedThreadPool(); 39 for (int i = 0; i < 10; i++) 40 es.execute(new Run(it, 100)); 41 42 //等待子线程结束 43 TimeUnit.SECONDS.sleep(1); 44 45 if (it.getValue() != 3 * 10 * 100) 46 { 47 System.out.println("出现竞争:value=" + it.getValue()); 48 } 49 else 50 { 51 System.out.println("未出现竞争:value=" + it.getValue()); 52 } 53 } 54 55 } 56 57 class IncreaseThree 58 { 59 protected int value = 0; 60 61 protected void increaseThree() 62 { 63 value++; 64 //切换线程,增强效果 65 Thread.yield(); 66 value++; 67 Thread.yield(); 68 value++; 69 Thread.yield(); 70 } 71 72 public int getValue() 73 { 74 return value; 75 } 76 } 77 78 class SynchronizedIncrease1 extends IncreaseThree 79 { 80 public void increaseThree() 81 { 82 synchronized(this) 83 { 84 value++; 85 //切换线程,增强效果 86 Thread.yield(); 87 value++; 88 Thread.yield(); 89 value++; 90 Thread.yield(); 91 } 92 } 93 } 94 95 class SynchronizedIncrease2 extends IncreaseThree 96 { 97 public synchronized void increaseThree() 98 { 99 value++; 100 //切换线程,增强效果 101 Thread.yield(); 102 value++; 103 Thread.yield(); 104 value++; 105 Thread.yield(); 106 } 107 } 108 109 class LockIncreaseThree extends IncreaseThree 110 { 111 Lock lock = new ReentrantLock(); 112 public void increaseThree() 113 { 114 lock.lock(); 115 try 116 { 117 value++; 118 //切换线程,增强效果 119 Thread.yield(); 120 value++; 121 Thread.yield(); 122 value++; 123 Thread.yield(); 124 }finally 125 { 126 lock.unlock(); 127 } 128 } 129 130 }
使用IncreaseThree对象时,会发生竞争运行一次就发生竞争:
出现竞争:value=2997
使用SynchronizedIncrease1, SynchronizedIncrease2, LockIncreaseThree对象时,运行多次也不会出现竞争。
原文:http://www.cnblogs.com/gatsbydhn/p/5117449.html