解決erlang和java同時操作一張表,造成鎖表問題,erlangjava

來源:互聯網
上載者:User

解決erlang和java同時操作一張表,造成鎖表問題,erlangjava

作者:張昌昌

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)"

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.