项目使用到集群环境,流程发送时如果确保一个流程不会被两个流程同时调用?
有一种办法是用文件锁的方式来实现。
代码如下:
锁接口:
- packagelock;
- importjava.io.FileNotFoundException;
- importjava.io.IOException;
- publicinterfaceLock{
- /**
- *检测是否被锁定
- *@returntrue被锁定,false空闲
- **/
- publicabstractbooleanisLocked()throwsFileNotFoundException;
- /**
- *获取锁资源
- *@returntrue成功锁定目标资源,false锁定操作失败
- **/
- publicabstractbooleanobtain()throwsIOException;
- /**
- *释放锁
- **/
- publicabstractvoidunlock();
- }
文件锁的实现:
- packagelock;
- importjava.io.File;
- importjava.io.FileNotFoundException;
- importjava.io.IOException;
- importjava.io.RandomAccessFile;
- importjava.nio.channels.FileChannel;
- importjava.nio.channels.FileLock;
- importjava.nio.channels.OverlappingFileLockException;
- publicclassFileProgrameLockimplementsLock{
- privateStringcallerThreadID=null;
- privateStringlockFileName=null;
- FileChannelchannel=null;
- privateFileLocklock=null;
- publicstaticLockget(StringfileName,StringcallerThreadID){
- FileProgrameLockd=newFileProgrameLock(fileName);
- d.callerThreadID=callerThreadID;
- return(Lock)d;
- }
- publicFileProgrameLock(StringlockFileName){
- this.lockFileName=lockFileName;
- }
- /**
- *检测是否被锁定-不建议使用
- *@returntrue被锁定,false空闲
- *@deprecated
- **/
- publicbooleanisLocked()throwsFileNotFoundException{
- Filetf=newFile(lockFileName);
- if(!tf.exists()){
- returnfalse;
- }
- FileChannel__channel=newRandomAccessFile(tf,"rw").getChannel();
- FileLocktl=null;
- try{
- tl=__channel.tryLock();
- if(tl==null){
- returntrue;
- }else{
- returnfalse;
- }
- }catch(OverlappingFileLockExceptione){
- returntrue;
- }catch(IOExceptione){
- returntrue;
- }catch(Exceptione){
- returntrue;
- }finally{
- try{
- if(tl!=null){
- tl.release();
- }
- tl=null;
- if(__channel.isOpen()){
- __channel.close();
- }
- __channel=null;
- tf=null;
- }catch(IOExceptione){
- e.printStackTrace();
- }
- }
- }
- /**
- *获取锁资源
- *@returntrue成功锁定目标资源,false锁定操作失败
- **/
- publicbooleanobtain()throwsIOException{
- Filetf=newFile(lockFileName);
- createFile();
- channel=newRandomAccessFile(tf,"rw").getChannel();
- try{
- //System.out.println("getlock000>>>>>>>>>>>>>>>");
- lock=channel.lock();
- //System.out.println("getlock>>>>>>>>>>>>>>>");
- returntrue;
- }catch(OverlappingFileLockExceptione){
- returnfalse;
- }catch(Exceptione){
- returnfalse;
- }
- }
- /**
- *释放锁
- **/
- publicvoidunlock(){
- try{
- if(lock!=null){
- lock.release();
- }
- System.out.println(callerThreadID+"unlockXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- if(channel!=null&&channel.isOpen()){
- channel.close();
- }
- lock=null;
- channel=null;
- this.deleteFile();
- }catch(IOExceptione){
- }
- }
- protectedvoidfinalize()throwsThrowable{
- System.out.println(callerThreadID+this.getClass()+".finalize()");
- super.finalize();
- }
- privatevoidcreateFile()throwsIOException{
- try{
- Filetf=newFile(lockFileName);
- if(!tf.exists()){
- tf.createNewFile();
- }
- tf=null;
- }catch(IOExceptione){
- System.out.println(e+lockFileName);
- throwe;
- }
- }
- privatevoiddeleteFile(){
- Filetf=newFile(lockFileName);
- if(tf.exists()){
- tf.delete();
- }
- tf=null;
- }
- }
工厂类:
- packagelock;
- importjava.io.File;
- importjava.io.FileNotFoundException;
- importjava.io.IOException;
- publicclassMakeLockimplementsRunnable{
- privateStringthreadID="";
- publicvoidrun(){
- try{
- while(true){
- test2(threadID);
- Thread.sleep(200);
- }
- }catch(IOExceptione){
- System.out.println(e);
- e.printStackTrace();
- }catch(InterruptedExceptione){
- System.out.println(e);
- }
- }
- publicvoidtest2(StringthreadID)throwsFileNotFoundException,IOException,InterruptedException{
- Locklock=newMakeLock(threadID).getLock("c:/001/lockfile001.lock",threadID);
- System.out.println(threadID+":obtain...");
- booleanb=lock.obtain();
- //当有重叠时会发生等待,所以外侧先执行isLocked()判断
- System.out.println(threadID+":obtained"+b);
- if(b){//执行业务逻辑
- Thread.sleep(390);
- for(inti=0;i<Integer.MAX_VALUE;i++){
- ;
- }
- lock.unlock();
- }
- lock=null;
- }
- publicMakeLock(StringthreadID){
- this.threadID=threadID;
- }
- publicLockgetLock(Stringname,StringthreadID){
- finalStringBufferbuf=newStringBuffer();
- returnFileProgrameLock.get(name,threadID);
- }
- }
使用方法:
- publicvoidtest2(StringthreadID)throwsFileNotFoundException,IOException,InterruptedException{
- Locklock=newMakeLock(threadID).getLock("c:/001/lockfile001.lock",threadID);
- if(!lock.isLocked()){
- System.out.println(threadID+":obtain...");
- booleanb=lock.obtain();
- System.out.println(threadID+":obtained"+b);
- if(b){//执行业务逻辑
- Thread.sleep(390);
- for(inti=0;i<Integer.MAX_VALUE;i++){
- ;
- }
- lock.unlock();
- }
- }else{
- System.out.println(threadID+":can'tgetalock:"+lock);
- }
- lock=null;
- }
多线程调用测试:
- publicstaticvoidmain(String[]args){
- //newAAA().test();
- System.out.println("=========================================");
- Threadth1=newThread(newMakeLock("====================thread1===================="));
- Threadth2=newThread(newMakeLock("####################thread2####################"));
- Threadth3=newThread(newMakeLock("@@@@@@@@@@@@@@@@@@@@thread3@@@@@@@@@@@@@@@@@@@@"));
- Threadth4=newThread(newMakeLock("$$$$$$$$$$$$$$$$$$$$thread4$$$$$$$$$$$$$$$$$$$$"));
- Threadth5=newThread(newMakeLock("&&&&&&&&&&&&&&&&&&&&thread5&&&&&&&&&&&&&&&&&&&&"));
- th1.start();
- th2.start();
- th3.start();
- th4.start();
- th5.start();
- }
=================
经测试可以在共享文件系统下工作。
附件中AAA.java多线程测试代码可以直接运行。
项目使用到集群环境,流程发送时如果确保一个流程不会被两个流程同时调用?
有一种办法是用文件锁的方式来实现。
代码如下:
锁接口:
- packagelock;
- importjava.io.FileNotFoundException;
- importjava.io.IOException;
- publicinterfaceLock{
- /**
- *检测是否被锁定
- *@returntrue被锁定,false空闲
- **/
- publicabstractbooleanisLocked()throwsFileNotFoundException;
- /**
- *获取锁资源
- *@returntrue成功锁定目标资源,false锁定操作失败
- **/
- publicabstractbooleanobtain()throwsIOException;
- /**
- *释放锁
- **/
- publicabstractvoidunlock();
- }
文件锁的实现:
- packagelock;
- importjava.io.File;
- importjava.io.FileNotFoundException;
- importjava.io.IOException;
- importjava.io.RandomAccessFile;
- importjava.nio.channels.FileChannel;
- importjava.nio.channels.FileLock;
- importjava.nio.channels.OverlappingFileLockException;
- publicclassFileProgrameLockimplementsLock{
- privateStringcallerThreadID=null;
- privateStringlockFileName=null;
- FileChannelchannel=null;
- privateFileLocklock=null;
- publicstaticLockget(StringfileName,StringcallerThreadID){
- FileProgrameLockd=newFileProgrameLock(fileName);
- d.callerThreadID=callerThreadID;
- return(Lock)d;
- }
- publicFileProgrameLock(StringlockFileName){
- this.lockFileName=lockFileName;
- }
- /**
- *检测是否被锁定-不建议使用
- *@returntrue被锁定,false空闲
- *@deprecated
- **/
- publicbooleanisLocked()throwsFileNotFoundException{
- Filetf=newFile(lockFileName);
- if(!tf.exists()){
- returnfalse;
- }
- FileChannel__channel=newRandomAccessFile(tf,"rw").getChannel();
- FileLocktl=null;
- try{
- tl=__channel.tryLock();
- if(tl==null){
- returntrue;
- }else{
- returnfalse;
- }
- }catch(OverlappingFileLockExceptione){
- returntrue;
- }catch(IOExceptione){
- returntrue;
- }catch(Exceptione){
- returntrue;
- }finally{
- try{
- if(tl!=null){
- tl.release();
- }
- tl=null;
- if(__channel.isOpen()){
- __channel.close();
- }
- __channel=null;
- tf=null;
- }catch(IOExceptione){
- e.printStackTrace();
- }
- }
- }
- /**
- *获取锁资源
- *@returntrue成功锁定目标资源,false锁定操作失败
- **/
- publicbooleanobtain()throwsIOException{
- Filetf=newFile(lockFileName);
- createFile();
- channel=newRandomAccessFile(tf,"rw").getChannel();
- try{
- //System.out.println("getlock000>>>>>>>>>>>>>>>");
- lock=channel.lock();
- //System.out.println("getlock>>>>>>>>>>>>>>>");
- returntrue;
- }catch(OverlappingFileLockExceptione){
- returnfalse;
- }catch(Exceptione){
- returnfalse;
- }
- }
- /**
- *释放锁
- **/
- publicvoidunlock(){
- try{
- if(lock!=null){
- lock.release();
- }
- System.out.println(callerThreadID+"unlockXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- if(channel!=null&&channel.isOpen()){
- channel.close();
- }
- lock=null;
- channel=null;
- this.deleteFile();
- }catch(IOExceptione){
- }
- }
- protectedvoidfinalize()throwsThrowable{
- System.out.println(callerThreadID+this.getClass()+".finalize()");
- super.finalize();
- }
- privatevoidcreateFile()throwsIOException{
- try{
- Filetf=newFile(lockFileName);
- if(!tf.exists()){
- tf.createNewFile();
- }
- tf=null;
- }catch(IOExceptione){
- System.out.println(e+lockFileName);
- throwe;
- }
- }
- privatevoiddeleteFile(){
- Filetf=newFile(lockFileName);
- if(tf.exists()){
- tf.delete();
- }
- tf=null;
- }
- }
工厂类:
- packagelock;
- importjava.io.File;
- importjava.io.FileNotFoundException;
- importjava.io.IOException;
- publicclassMakeLockimplementsRunnable{
- privateStringthreadID="";
- publicvoidrun(){
- try{
- while(true){
- test2(threadID);
- Thread.sleep(200);
- }
- }catch(IOExceptione){
- System.out.println(e);
- e.printStackTrace();
- }catch(InterruptedExceptione){
- System.out.println(e);
- }
- }
- publicvoidtest2(StringthreadID)throwsFileNotFoundException,IOException,InterruptedException{
- Locklock=newMakeLock(threadID).getLock("c:/001/lockfile001.lock",threadID);
- System.out.println(threadID+":obtain...");
- booleanb=lock.obtain();
- //当有重叠时会发生等待,所以外侧先执行isLocked()判断
- System.out.println(threadID+":obtained"+b);
- if(b){//执行业务逻辑
- Thread.sleep(390);
- for(inti=0;i<Integer.MAX_VALUE;i++){
- ;
- }
- lock.unlock();
- }
- lock=null;
- }
- publicMakeLock(StringthreadID){
- this.threadID=threadID;
- }
- publicLockgetLock(Stringname,StringthreadID){
- finalStringBufferbuf=newStringBuffer();
- returnFileProgrameLock.get(name,threadID);
- }
- }
使用方法:
- publicvoidtest2(StringthreadID)throwsFileNotFoundException,IOException,InterruptedException{
- Locklock=newMakeLock(threadID).getLock("c:/001/lockfile001.lock",threadID);
- if(!lock.isLocked()){
- System.out.println(threadID+":obtain...");
- booleanb=lock.obtain();
- System.out.println(threadID+":obtained"+b);
- if(b){//执行业务逻辑
- Thread.sleep(390);
- for(inti=0;i<Integer.MAX_VALUE;i++){
- ;
- }
- lock.unlock();
- }
- }else{
- System.out.println(threadID+":can'tgetalock:"+lock);
- }
- lock=null;
- }
多线程调用测试:
- publicstaticvoidmain(String[]args){
- //newAAA().test();
- System.out.println("=========================================");
- Threadth1=newThread(newMakeLock("====================thread1===================="));
- Threadth2=newThread(newMakeLock("####################thread2####################"));
- Threadth3=newThread(newMakeLock("@@@@@@@@@@@@@@@@@@@@thread3@@@@@@@@@@@@@@@@@@@@"));
- Threadth4=newThread(newMakeLock("$$$$$$$$$$$$$$$$$$$$thread4$$$$$$$$$$$$$$$$$$$$"));
- Threadth5=newThread(newMakeLock("&&&&&&&&&&&&&&&&&&&&thread5&&&&&&&&&&&&&&&&&&&&"));
- th1.start();
- th2.start();
- th3.start();
- th4.start();
- th5.start();
- }
=================
经测试可以在共享文件系统下工作。
附件中AAA.java多线程测试代码可以直接运行。