Synchronized的替代

    對於一些初級的程序員來說使用Synchronized來解決同步問題是不太容易理解的,那不如用javaSE 5 中的鎖來解決線程同步問題更加容易理解。

   首先很多人忽略了多線程的本質,我們首先要知道多線程並不是併發的,而是串行的,也就是說執行完一個再執行下一個。那麼多線程編程最大問題就是會不會有同時調用一個資源的可能。那答案必然是有。怎麼解決?爲什麼要解決?我不想闡述太多的原理,因爲在csdn上很多研究者,我這個開發者不想在這裏班門弄斧。簡單的說一下:如果同時調用一個資源就會涉及到一個最簡單的問題,誰先來使用,如果有一方正在使用怎麼解決的問題。那怎麼解決?很簡單一個一個來。(其實本來是想做一個並行的例子,時間不夠下次吧。)對於現階段的java開發絕大多數還是使用單cpu資源的,所以只能一個一個的執行,但是爲了防止“自己”在使用的時候不被打擾,我們需要上鎖。提一個不貼切的很直白的問題大家就能明白了。有人會上WC不鎖門嗎?我想問題一說出來會有人笑,但是確實如此。

    下面是用concurrency中的ReentrantLock替換原來的Synchronized

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.io.*;

public class WriteAndReadTest implements Runnable {
private final Lock lock = new ReentrantLock();
private BufferedReader fr;
private FileWriter fw;
private State s;
public WriteAndReadTest(State s) throws IOException{
        this.s = s;
        if(s.equals(State.讀取操作))
        fr = new BufferedReader(new FileReader(new File
        ("F://MyEclipseWorkSpace//ConCurrentProject//src//test//files//test.txt")));
        else if(s.equals(State.寫入操作))
        fw = new FileWriter(new File
        ("F://MyEclipseWorkSpace//ConCurrentProject//src//test//files//test.txt"),true);
}

@Override
public void run() {
// TODO Auto-generated method stub
        lock.lock();//Lock上鎖
        try
        {
                Thread.sleep(500);
                //synchronized(this){         原始方式:synchronized監視器,監視當前對象
                if(s.equals(State.讀取操作)){
                        String tmp;
                        while((tmp=fr.readLine())!=null){
                                System.out.print(tmp);
                        }
                        fr.close();
                }
                else if(s.equals(State.寫入操作)){
                        String str = "this is write test";
                        for(int a=0;a<10;a++){
                                fw.write(str+"/n");
                                System.out.println("寫入"+a+"行");
                        }
                        fw.close();
                }
                //}        end
        }
        catch(IOException em){
                System.out.println("this io exceptions");
                em.printStackTrace();
                }
        catch(InterruptedException em){
                System.out.println("this io interruptedexception");
                em.printStackTrace();
                }
        catch(Exception em){
                System.out.println("this io exception");
                em.printStackTrace();
                }
        lock.unlock();//解鎖
        }
}

    上面的State是一個枚舉。代碼:

public enum State
{
 開始{int getInfo(){return 1;}},
 結束{int getInfo(){return -1;}},
 讀取操作{int getInfo(){return 100;}},
 寫入操作{int getInfo(){return 101;}}
}

    可以看出上面加了鎖以後同樣不會出現髒讀,但是注意不要胡亂的使用鎖,會降低效率。

    今天就寫到這太晚了,睡了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章