用于处理一般方法的最佳设计模式,一次可由多个线程访问

时间:2016-01-13 20:56:47

标签: java multithreading spring design-patterns

我尝试创建一个静态方法,一次可以通过不同类的多个方法访问。

由于它是静态的,它会被锁定,我会遇到不同的结果和性能问题。

有没有更好的方法让这些方法一次可以被多种方法访问?

有没有更好的方法在Spring Framework中处理这个问题?

  public class TestUtil {

  public static SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");

   public static java.sql.Date getLastDayOfMonth(String month,intyear) 
    throws ParseException{      
    switch (month) {
    case "jan": 
             return new java.sql.Date(f.parse(year+"-1-31").getTime());
    case "feb": if(isLeapYear(year))
             return new java.sql.Date(f.parse(year+"-2-29").getTime());
             else
              return new java.sql.Date(f.parse(year+"-2-28").getTime());
    case "mar":                
             return new java.sql.Date(f.parse(year+"-3-31").getTime());

    case "apr": 
             return new java.sql.Date(f.parse(year+"-4-30").getTime());
    case "may": 
             return new java.sql.Date(f.parse(year+"-5-31").getTime());
    case "jun": 
             return new java.sql.Date(f.parse(year+"-6-30").getTime());
    case "jul": 
             return new java.sql.Date(f.parse(year+"-7-31").getTime());
    case "aug": 
             return new java.sql.Date(f.parse(year+"-8-31").getTime());
    case "sep": 
             return new java.sql.Date(f.parse(year+"-9-30").getTime());
    case "oct": 
             return new java.sql.Date(f.parse(year+"-10-31").getTime());
    case "nov": 
             return new java.sql.Date(f.parse(year+"-11-30").getTime());
    case "dec": 
             return new java.sql.Date(f.parse(year+"-12-31").getTime());        
    default: month = "Invalid month";
    return null;  
}           
}
}

3 个答案:

答案 0 :(得分:1)

编辑

你的技术非常糟糕。

答案

使用Spring将实例化对象注入到类中。 单一的默认类型是 这就是你想要的。 不要在实用程序方法中存储任何状态。 使用非静态方法。

不要解析String来查找日期, 而是使用Calendar类。 此外,您可以轻松地不使用静态SimpleDateFormat并只使用本地。 这是一些代码(使用静态SimpleDateFormat)。

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class Dates
{
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    private static Date getLastDay(final int month, final int year)
    {
        final Calendar calendar = Calendar.getInstance();
        Date returnValue;

        switch (month)
        {
            case Calendar.DECEMBER:
                calendar.set(Calendar.YEAR, year + 1);
                calendar.set(Calendar.MONTH, Calendar.JANUARY);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                calendar.add(Calendar.DAY_OF_YEAR, -1);

                returnValue = calendar.getTime();

                break;

            case Calendar.JANUARY:
                calendar.set(Calendar.YEAR, year);
                calendar.set(Calendar.MONTH, Calendar.FEBRUARY);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                calendar.add(Calendar.DAY_OF_YEAR, -1);

                returnValue = calendar.getTime();
                break;

            case Calendar.FEBRUARY:
                calendar.set(Calendar.YEAR, year);
                calendar.set(Calendar.MONTH, Calendar.MARCH);
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                calendar.add(Calendar.DAY_OF_YEAR, -1);

                returnValue = calendar.getTime();
                break;

            default:
                returnValue = new Date();
                break;
        }

        return returnValue;
    }

    public static void main(
        String[] args)
    {
        Date date;

        System.out.println("Dec 2015: " + dateFormat.format(getLastDay(Calendar.DECEMBER, 2015)));
        System.out.println("Jan 2015: " + dateFormat.format(getLastDay(Calendar.JANUARY, 2015)));
        System.out.println("Feb 2015: " + dateFormat.format(getLastDay(Calendar.FEBRUARY, 2015)));
        System.out.println("Feb 2016: " + dateFormat.format(getLastDay(Calendar.FEBRUARY, 2016)));
    }

}

答案 1 :(得分:1)

您可以为安全做的最好的事情之一是消除多个线程的状态更改,并且最常用的方法是使用不可变对象。

它经常被忽视,但SimpleDateFormat具有可变状态(它跟踪调用之间的解析操作状态)。因此,正如您所发现的那样,同时使用多个线程并不起作用。

寻找消除共享状态的替代方案。在这种情况下,它很简单:只需在Java 8中使用改进的API来表示日期和时间:

private static final DateTimeFormatter f; 

static {
  DateTimeFormatterBuilder b = new DateTimeFormatterBuilder();
  b.parseCaseInsensitive();
  b.parseDefaulting(ChronoField.DAY_OF_MONTH, 1);
  b.appendPattern("uuuuMMM");
  f = b.toFormatter(Locale.US); /* f is an immutable object! */
}

public static LocalDate getLastDayOfMonth(String month, int year)
{
  LocalDate first = LocalDate.parse(year + month, f);
  LocalDate last = first.with(TemporalAdjusters.lastDayOfMonth());
  return last;
}

答案 2 :(得分:0)

如果绝对需要静态字段,请将其更改为ThreadLocal<U>,在您的情况下为public static ThreadLocal<SimpleDateFormat> f = new ThreadLocal<SimpleDateFormat>();,否则,将字段更改为静态方法中的局部变量你会没事的。