2011-12-27 7 views
2

フレンド、Dateを操作する静的メソッドです。マルチスレッドの問題

私は私の生産コードの変更を抽出しています。

次のコードを実行すると、auditdate1を渡してgetDateEndOfDayを実行していますが、「TestDateProblem:Problem with getYear method」が表示されます。

日付が正しく設定されているため、私の生産コードのキャッチブロック内のロガーでこれを見ることができたため、実際にはこの問題を解決できませんでした。私はあなたの助けがひどく必要です。

このgetDateEndOfDayメソッドは多くのパブリックメソッドから呼び出され、複数のスレッドがこれらの静的メソッドを同時に呼び出す可能性があります。

package test; 

import java.util.Arrays; 

import java.util.Date; 

import java.util.GregorianCalendar; 


public class TestDateProblem { 

    public static void main(String args[]) { 
     /* 
     * This is the date format that is mostly used. Logger shows this kind 
     * of date during Exception. 
     */ 
     String auditdate1 = "2011-12-27"; 
     // Rarely sent this way. 
     String auditdate2 = "27-12-2011"; 
     /* 
     * We don't send this way but I'm sure the problem occurs if the date goes this 
     * way. As far as the inputs are concerned, it doesn't go like this. 
     */ 
     String auditdate3 = "27-2011-12"; 

     try { 

      System.out.println("Result1:" + getDateEndOfDay(auditdate1)); 

      System.out.println("Result2:" + getDateEndOfDay(auditdate2)); 
      // simulating problem? 
      System.out.println("Result3:" + getDateEndOfDay(auditdate3)); 
     } catch (Exception e) { 
      System.out.println("auditdate1:" + auditdate1); 
     } 
    } 

    /* 
    * This getDateEndOfDay(.) method is called from many public methods and it 
    * may be possible that multiple threads are calling these static methods at 
    * the same time. 
    */ 
    public static Date getDateEndOfDay(String dateparam) throws Exception { 
     String separator = "/"; 
     dateparam = dateparam.replace("-", separator); 
     String[] strP = dateparam.split(separator); 
     Integer year = getYear(strP); 
     Integer month = getMonth(strP); 
     Integer day = getDay(strP); 
     GregorianCalendar cal = new GregorianCalendar(year, month - 1, day, 23, 
       59, 00); 

     return cal.getTime(); 
    } 

    private static Integer getYear(String[] dateComponents) throws Exception { 
     if (dateComponents.length != 3) { 
      return 1900; 
     } 
     System.out 
       .println("dateComponents::" + Arrays.toString(dateComponents)); 

     Integer val1 = Integer 
       .valueOf(dateComponents[0].startsWith("0") ? dateComponents[0] 
         .substring(1) : dateComponents[0]); 
     Integer val2 = Integer 
       .valueOf(dateComponents[2].startsWith("0") ? dateComponents[2] 
         .substring(1) : dateComponents[2]); 
     if (val1 > 1900) { 
      return val1; 
     } else if (val2 > 1900) { 
      return val2; 
     } else { 
      // Original code throws exception instead of printing to console. 
      System.out.println("TestDateProblem: Problem with getYear method."); 
      throw new Exception(); 
     } 
    } 

    private static Integer getDay(String[] dateComponents) { 
     if (dateComponents.length != 3) { 
      return -1; 
     } 

     Integer val1 = Integer 
       .valueOf(dateComponents[0].startsWith("0") ? dateComponents[1] 
         .substring(1) : dateComponents[0]); 
     Integer val2 = Integer 
       .valueOf(dateComponents[2].startsWith("0") ? dateComponents[1] 
         .substring(1) : dateComponents[2]); 

     if (val1 <= 31) { 
      return val1; 
     } else if (val2 <= 31) { 
      return val2; 
     } else { 
      System.out.println("TestDateProblem: Problem with getDay method."); 
      return 0; 
     } 
    } 

    private static Integer getMonth(String[] dateComponents) { 
     if (dateComponents.length != 3) { 
      return 0; 
     } 

     Integer val1 = Integer 
       .valueOf(dateComponents[1].startsWith("0") ? dateComponents[1] 
         .substring(1) : dateComponents[1]); 

     if (val1 <= 12 && val1 >= 1) { 
      return val1; 
     } else { 
      System.out 
        .println("TestDateProblem:: Problem with getMonth method"); 
      return 0; 
     } 
    } 
} 
+1

確かに読みにくい無意味なコードがたくさんあります。私のお気に入りは 'Integer val1 = Integer .valueOf(dateComponents [0] .startsWith(" 0 ")?dateComponents [0] .substring(1):dateComponents [0])'ユニットテストを追加して使用することをお勧めします失敗した場合のデバッガ –

+0

あなたの答えをありがとう。私は元のコードを書いていない。私はときどき発生する生産バグを修正しようとしています。だから、これは常に再現可能ではないので、私はいくつかのスレッドの問題を疑っていました。この問題は、新しいバッチを実行しているときに発生することがあります。 – matlapudi

+0

無効なメッセージの完全な入力を表示するためにエラーメッセージを変更できますか?そうすることで、無効な入力を使用すると毎回同じエラーが発生することがわかります。 –

答えて

1

auditdate3ではなく、auditdate3に問題があります。 27-2011-12を日付として渡し、年を抽出しようとします。最初の日付と最後の日付のコンポーネントをチェックしますが、27と12は有効な年ではありません。だからあなたは例外を持っている。デバッガでコードを実行する必要があります。

+0

お時間をいただきありがとうございます。私は混乱のために申し訳ありません。実際の生産コードでは、yyyy-mm-dd形式のauditdate1しかcatchブロック内のロガーメッセージで確認できませんでした。私はちょうどこのように私たちが問題を確実に言うと言うためにauditdate3を述べました。スレッドがオブジェクトを変更してこの種の問題を引き起こすかどうか疑問に思っていましたか? – matlapudi

2

このコードにはスレッドセーフの問題があるとは考えられません。これには、静的変数や、非局所変数が操作される他の手段はありません。おそらく非スレッドセーフである可能性のあるコードが呼び出される唯一の場所は、新しいGregorianCalendarオブジェクトを作成するときですが、そのドキュメントではスレッドセーフではないことを示唆するものはないので、そうは思わないでしょう。

また、Javaに日付解析の機能はまだありませんか?なぜjava.text.SimpleDateFormatの解析メソッドを使用しないのですか?これよりもはるかに簡単ではないでしょうか?

+0

こんにちはアーウィン、あなたの答えをよろしくお願いします。私は元のコードを書いていない。彼らはユーザーからの "yyyy/mm/dd"と "dd/mm/yyy"の両方の形式を受け入れるこのコードを書いており、その日は '05'または '5'になる可能性があるので、部分文字列。キャッチブロックのロガーには、日付(2011-12-6)と形式(yyyy-mm-dd)の入力が表示されます。私は実際に時々だけ発生する生産バグを修正しようとしています。だから、これは常に再現可能ではないので、私はいくつかのスレッドの問題を疑っていました。この問題は、新しいバッチを実行しているときに発生することがあります。私を助けてください。 – matlapudi

+0

実際のデータがどのような原因で発生しているのかわからなければ、私は本当に助けにはなりません。私は、それがスレッドの問題ではないという非常に強い確信をもって、あなたに伝えることができます。 –

+0

こんにちはアーウィン、機能に入る日付は "2011-12-6"です。そして、このようになったら、私がここで示したサンプルプログラムでは何の問題も起こらないはずですが、プロダクションでは時々だけ例外がスローされます。あなたが知りたいデータを教えてください。 – matlapudi

2

コードは不必要に冗長ですが、合理的にも明らかです。あなたが持っている問題は、日付がyyyy/mm/dd形式かdd/mm/yyyy形式であるかどうかを調べることです。ただし、yy/mm/dd形式のようなものを与えると、それはあなたが見ているエラーです。

デバッガでコードを実行すると、これが確認されます。

それが問題

​​

あなたはそれを無効フォーマットされた日付を与えていると、それはそれを処理する方法を知らないので、それは間違いなくそれを拒否していると説明しているように私は再びこのコメントを読んでいました。

+0

あなたの答えをありがとう。私は元のコードを書いていない。しかし、私は、ユーザーからの "yyyy/mm/dd"と "dd/mm/yyy"の両方の形式を受け入れるこのコードを書いたことを伝えることができ、その日は '05'または '5'なぜなら、部分文字列にいくつかのコードがあるからです。ロガーには有効な日付(2011-12-6)と有効な形式(yyyy-mm-dd)が表示されます。私は実際に時々だけ発生する生産バグを修正しようとしています。だから、これは常に再現可能ではないので、私はいくつかのスレッドの問題を疑っていました。この問題は、新しいバッチを実行しているときに発生することがあります。 – matlapudi

+0

失敗した文字列または年が表示された場合は、その文字列が破損しているかどうかを確認することができます。コードから、このコードではスレッドの問題ではないようですが、これを呼び出すコードではスレッドの問題である可能性があります。あなたが 'Integer.parseInt(" 05 ")を実行した場合、部分文字列が冗長であるように、' Integer'オブジェクトではなく '5'を取得しintを返します。 –

+0

ありがとうございます。あなたが正しいです。それは他の人によって書かれた非常に古いコードでした。私はそれを改善します。 – matlapudi

関連する問題