對於一些初級的程序員來說使用Synchronized來解決同步問題是不太容易理解的,那不如用javaSE 5 中的鎖來解決線程同步問題更加容易理解。
首先很多人忽略了多線程的本質,我們首先要知道多線程並不是併發的,而是串行的,也就是說執行完一個再執行下一個。那麼多線程編程最大問題就是會不會有同時調用一個資源的可能。那答案必然是有。怎麼解決?爲什麼要解決?我不想闡述太多的原理,因爲在csdn上很多研究者,我這個開發者不想在這裏班門弄斧。簡單的說一下:如果同時調用一個資源就會涉及到一個最簡單的問題,誰先來使用,如果有一方正在使用怎麼解決的問題。那怎麼解決?很簡單一個一個來。(其實本來是想做一個並行的例子,時間不夠下次吧。)對於現階段的java開發絕大多數還是使用單cpu資源的,所以只能一個一個的執行,但是爲了防止“自己”在使用的時候不被打擾,我們需要上鎖。提一個不貼切的很直白的問題大家就能明白了。有人會上WC不鎖門嗎?我想問題一說出來會有人笑,但是確實如此。
下面是用concurrency中的ReentrantLock替換原來的Synchronized
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);
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();
}
}
catch(IOException em){
System.out.println("this io exceptions");
em.printStackTrace();
}
System.out.println("this io interruptedexception");
em.printStackTrace();
}
catch(Exception em){
System.out.println("this io exception");
em.printStackTrace();
}
}
}
上面的State是一個枚舉。代碼:
{
開始{int getInfo(){return 1;}},
結束{int getInfo(){return -1;}},
讀取操作{int getInfo(){return 100;}},
寫入操作{int getInfo(){return 101;}}
}
可以看出上面加了鎖以後同樣不會出現髒讀,但是注意不要胡亂的使用鎖,會降低效率。
今天就寫到這太晚了,睡了。