对于一些初级的程序员来说使用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;}}
}
可以看出上面加了锁以后同样不会出现脏读,但是注意不要胡乱的使用锁,会降低效率。
今天就写到这太晚了,睡了。