在线阅读加锁的功能 或者JAVA悲观锁

我想实现一个 在线阅读 加锁的功能
就是当这个文档在阅读的时候 其他的不可以访问并且等到一个提示 这个有什么方法。
也可以理解为 我就是想用JAVA 实现 数据库的 悲观锁。

2个回答

[code="java"]
class TestLock{
private static Map pool = new ConcurrentHashMap();
public static void main(String[] args) {
for(int i=0;i<5;i++){
new Thread(
new Runnable(){
public void run(){
try {
//使用MD5,可以区分文件名不同但内容相同的文档
String md5Str =MD5Helper.getFileMD52(new File("d:"+File.separator+"a.doc"));
if(pool.get(md5Str)==null){
pool.put(md5Str, md5Str);
}
//同步 保证同一份文档 仅允许同一个用户阅读
synchronized (pool.get(md5Str)) {
System.out.println(Thread.currentThread().getName()+"正在阅读...");

//移除
pool.remove(md5Str);
System.out.println(Thread.currentThread().getName()+"阅读结束!!!...");

}
} catch (IOException e) {
e.printStackTrace();
}
}

}

        ).start();
    }

}

}
class MD5Helper{
public static String getFileMD52(File file) throws IOException {
String res = "";
ByteArrayOutputStream out = new ByteArrayOutputStream();
FileInputStream in = null;
try {
in = new FileInputStream(file);
byte[] inb = new byte[1024];
while (in.read(inb) != -1) {
out.write(inb);
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(in!=null){
in.close();
}
in = null;
}
try {
MessageDigest md5C = MessageDigest.getInstance("MD5");
byte[] b = md5C.digest(out.toByteArray());
res = byteArrayToHexString(b);
} catch (final NoSuchAlgorithmException e) {
}finally{
out.close();
out = null;
}
return res;
}

public static String byteArrayToHexString(byte in[]) {
    byte ch = 0x00;
    int i = 0;
    if (in == null || in.length <= 0)
        return null;

    String pseudo[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
            "A", "B", "C", "D", "E", "F" };
    StringBuffer out = new StringBuffer(in.length * 2);

    while (i < in.length) {
        ch = (byte) (in[i] & 0xF0); // Strip off high nibble
        ch = (byte) (ch >>> 4);
        // shift the bits down
        ch = (byte) (ch & 0x0F);
        // must do this is high order bit is on!
        out.append(pseudo[(int) ch]); // convert the nibble to a String
                                        // Character
        ch = (byte) (in[i] & 0x0F); // Strip off low nibble
        out.append(pseudo[(int) ch]); // convert the nibble to a String
                                        // Character
        out.append(" ");
        i++;
    }
    String rslt = new String(out);
    rslt = rslt.trim();
    return rslt;
}

}

[/code]

qb888_0451
qb888_0451 首先感谢楼上的两位,你们的代码都能运行。我也能写出。但是你们没有注意到的就是 WEB开发 在页面要一句话。。其实就是多线程要返回值。。这个回去我具体的研究了一下业务。其实是我写错了业务。对不起了 感谢二位了。。
大约 8 年之前 回复

这个问题相对简单,写一个单例的类来作锁定检查:

[code="java"]
public class LockPool{
private Map pool = new ConcurrentHashMap();
private LockPool(){}
private LockPool instance;
public LockPool getInstance(){
if(instance == null){
instance = new LockPool();
}
return instance;
}
public boolean checkLock(String s){
if(pool.containsKey(s)){
return pool.get(s);
}
return false;
}
public void addLock(String s){
pool.put(s, true);
}
public void removeLock(String s){
pool.put(s, false);
pool.remove(s);
}
}
[/code]

使用:
[code="java"]
//用户要阅读的文件名, 假设为 a.txt
String filename = "a.txt";
if(LockPool.getInstance().checkPool(filename)){
//已经锁定了,提示用户
System.out.println("抱歉,该文档已经被锁定了,你不能阅读。");
}else{
//没有锁定,用户可以进行阅读

//首先对该文档进行加锁
LockPool.getInstance().addLock(filename);
//阅读
System.out.println("正在阅读a.txt...");
//阅读完毕后,解除锁定
LockPool.getInstance().removeLock(filename);
}
[/code]

qb888_0451
qb888_0451 首先感谢楼上的两位,你们的代码都能运行。我也能写出。但是你们没有注意到的就是 WEB开发 在页面要一句话。。其实就是多线程要返回值。。这个回去我具体的研究了一下业务。其实是我写错了业务。对不起了 感谢二位了。。
大约 8 年之前 回复
立即提问
相关内容推荐