今天寫synchronized用例的時候,兩個線程共享一個對象數據,當操作i的時候,在同步代碼塊外面判斷了一次i<100,但是每一次跑,都會出現i=100,的情況,此時我想起了單例模式的雙重校驗鎖,為什么要判斷兩次呢?因為可能出現線程1和線程2,在i=99的時候,同時判斷了一次,都進到了for循環里面,此時線程1進入同步代碼塊,線程2進如阻塞隊列,當線程1跑出代碼塊后,線程2進入同步代碼塊,線程1對i進行加一操作后,i變成了100,線程2輸出100,所以要在同步代碼塊中再加一次判斷,判斷i的值
synchronized代碼塊使用起來比synchronized方法要靈活得多。因為也許一個方法中只有一部分代碼只需要同步,如果此時對整個方法用synchronized進行同步,會影響程序執行效率。而使用synchronized代碼塊就可以避免這個問題,synchronized代碼塊可以實現只對需要同步的地方進行同步
import java.util.ArrayList;
public class SynchronizedTest2 {
public static void main(String[] args) throws InterruptedException {
SychronizedTest2 synchronized2 = new SychronizedTest2();
Data data = synchronized2.new Data();
new Thread(new Runnable() {
@Override
public void run() {
data.insert();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
data.insert();
}
}).start();
Thread.currentThread().sleep(3000);
}
class Data{
private ArrayList<Integer> arr = new ArrayList<>();
private int i = 0;
public void insert(){
for(;i<100;i ++)
synchronized(this){
if(i<100){
if(!arr.contains(i)){
System.out.println(Thread.currentThread().getName()+" 正在插入"+i);
arr.add(i);
}
}
}
}
}
}