您的位置:首页 > 编程语言 > Java开发

解决erlang和java同时操作一张表,造成锁表问题

2015-01-22 23:58 393 查看
作者:张昌昌

1、问题描述

Erlang端通过odbc去写oracle一张表,同时java通过jdbc驱动也去写这张表,当同时多次发生这种写操作时,这个表就被锁。

2、问题解决

思路:利用适配器原理,适配erlang和java的数据库连接,让erlang端对数据表的操作与java端对该数据表的操作,分时序顺序进行,其中一端在进行写操作时上锁

另一端就不能操作,直到他操作完成释放锁,另一端才能操作。

该适配器采用java编写,通过otp.jar让erlang与java进行通信,erlang和java对数据表操作的连接都要从该适配器入

实现方式:

(1)java端

public class ConnectionAdaptor {

private static final ConnectionAdaptor instance = new ConnectionAdaptor("javaNode","theMailbox","secret");

private OtpNode node;

private static OtpMbox mbox;

private ReentrantLock lock = new ReentrantLock();

public static ConnectionAdaptor getInstance(){

return instance;

}

private ConnectionAdaptor(String nodeName,String mboxName,String cookie){

super();

try{

node=new OtpNode(nodeName,cookie);

}catch(IOException e){

e.printStackTrace();

}

System.out.print(node);

mbox = node.createMbox(mboxName);

}

private void process(){

while(true){

try{

OtpErlangObject msg = mbox.receive();

OtpErlangTuple t = (OtpErlangTuple)msg;

OtpErlangPid from = (OtpErlangPid)t.elementAt(0);

String name = ((OtpErlangString)t.elementAt(1)).stringValue();

if(name.equals("write_start"))

adaptor(1);

}catch(Exception e){

}

}

}

public static void main(String[] args){

//启动一个线程用于erlang消息的侦听

new Thread(){

public void run(){

ConnectionAdaptor.getInstance().process();

}

}.start();

//启动一个线程进行java端的数据表操作

new Thread(){

public void run()

{

for(int i=0;i<10;i++)

{

try{

try{

ConnectionAdaptor.getInstance().adaptor(2);

}catch(Exception e){

e.printStackTrace();

}

}catch(Exception e)

{

e.printStackTrace();

}

}

}

}.start();

}

public void adaptor(int type){

lock.lock();

if (type == 1)

{

while(true)

{

OtpErlangObject msg = mbox.receive();

OtpErlangTuple t = (OtpErlangTuple)msg;

OtpErlangPid from = ((OtpErlangString)t.elementAt(1)).stringValue();

if(name.equals("write_end"))

{

System.out.println("erlang write table end");

lock.unlock();

}

}

}

else

{

Thread.sleep(5000);

System.out.println("java write table end");

lock.unlock();

}

}

}

erlang端:

-module(erl_to_java).

-export([write_table/0,start/1]).

write_table() ->

{theMailbox,javaNode@zcc}!{self(),"write_start"},

timer:sleep(5000),

{theMailbox,javaNode@zcc}!{self(),"write_end"}.

start(N) ->

case N =:= 0 of

true -> ok;

false -> write_table(),start(N-1)

end.

3、时序图



4、问题总结

(1)java单例模式

(2)java与erlang通信

(3)java线程间锁机制

首先利用单例模式获取一个适配器对象,然后启动一个线程执行process(),侦听来自erlang端的写表消息,一旦有erlang发出写表请求,需加锁,在erlang进程中执行

写表操作后,向java进程发送写表结束请求,然后java进程释放锁,一旦有java端写表操作,便获取锁进行写表操作,之后释放锁,在java写表期间,erlang的写表操作必须等待,直到锁释放,反之亦然。

5、使用方法

(1)运行该适配器的java端需要安装erl的运行环境,需要导入OtpErlang.jar包;

(2)erlang端节点启动时,要和适配器单例创建时的cookie保持一致,同时

erl -sname erlangNode -setcookie secret -pa "erl_to_java.bin所在的路径" -eval "net_adm:ping(javaNode@zcc)"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐