Heim  >  Artikel  >  Java  >  Wie Java ThreadLocal verwendet, um threadspezifische Objekte zu speichern

Wie Java ThreadLocal verwendet, um threadspezifische Objekte zu speichern

WBOY
WBOYnach vorne
2023-06-03 09:32:081458Durchsuche

Verwenden Sie ThreadLocal, um threadspezifische Objekte zu speichern

ThreadLocal stellt threadspezifische Objekte bereit, auf die jederzeit während des Thread-Lebenszyklus zugegriffen werden kann, was die Implementierung einiger Logik erheblich erleichtert.

Es gibt zwei häufige Verwendungszwecke von ThreadLocal:

  1. Speichern Sie Thread-Kontextobjekte, um die Übergabe von Parametern auf mehreren Ebenen zu vermeiden.

  2. Speichern Sie nicht threadsichere Objekte, um gleichzeitige Aufrufe mit mehreren Threads zu vermeiden.

1. Speichern Sie das Thread-Kontextobjekt, um die Übergabe von Parametern auf mehreren Ebenen zu vermeiden. Nehmen Sie hier die Einstellung und Verwendung von Paging-Parametern im Quellcode des PageHelper-Plug-Ins.

Legen Sie den Paging-Parametercode fest:

/** 分页方法类 */public abstract class PageMethod {    /** 本地分页 */
    protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal<Page>();    /** 设置分页参数 */
    protected static void setLocalPage(Page page) {
        LOCAL_PAGE.set(page);
    }    /** 获取分页参数 */
    public static <T> Page<T> getLocalPage() {        return LOCAL_PAGE.get();
    }    /** 开始分页 */
    public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {
        Page<E> page = new Page<E>(pageNum, pageSize, count);
        page.setReasonable(reasonable);
        page.setPageSizeZero(pageSizeZero);
        Page<E> oldPage = getLocalPage();        if (oldPage != null && oldPage.isOrderByOnly()) {
            page.setOrderBy(oldPage.getOrderBy());
        }
        setLocalPage(page);        return page;
    }
}

Verwenden Sie den Paging-Parametercode:

/** 虚辅助方言类 */public abstract class AbstractHelperDialect extends AbstractDialect implements Constant {    /** 获取本地分页 */
    public <T> Page<T> getLocalPage() {        return PageHelper.getLocalPage();
    }    /** 获取分页SQL */
    @Override
    public String getPageSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds, CacheKey pageKey) {
        String sql = boundSql.getSql();
        Page page = getLocalPage();
        String orderBy = page.getOrderBy();        if (StringUtil.isNotEmpty(orderBy)) {
            pageKey.update(orderBy);
            sql = OrderByParser.converToOrderBySql(sql, orderBy);
        }        if (page.isOrderByOnly()) {            return sql;
        }        return getPageSql(sql, page, pageKey);
    }
    ...
}

Verwenden Sie den Paging-Plug-in-Code:

/** 查询用户函数 */public PageInfo<UserDO> queryUser(UserQuery userQuery, int pageNum, int pageSize) {
    PageHelper.startPage(pageNum, pageSize);
    List<UserDO> userList = userDAO.queryUser(userQuery);
    PageInfo<UserDO> pageInfo = new PageInfo<>(userList);    return pageInfo;
}

Wenn Sie die Paging-Parameter über Funktionsparameter an die Abfrageanweisung übergeben möchten, sofern Sie keine Änderungen vornehmen die MyBatis-bezogene Schnittstellenfunktion, sonst ist es unmöglich.

2. Speichern Sie nicht threadsichere Objekte, um gleichzeitige Aufrufe von mehreren Threads zu vermeiden.

Beim Schreiben einer Datumsformatierungstool-Funktion fällt mir als Erstes Folgendes ein:

/** 日期模式 */private static final String DATE_PATTERN = "yyyy-MM-dd";/** 格式化日期函数 */public static String formatDate(Date date) {    return new SimpleDateFormat(DATE_PATTERN).format(date);
}

Unter diesen muss DateFormat jedes Mal initialisiert werden Nachdem DateFormat als Konstante definiert wurde, wird es wie folgt geschrieben:

/** 日期格式 */private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");/** 格式化日期函数 */public static String formatDate(Date date) {    return DATE_FORMAT.format(date);
}

Da SimpleDateFormat nicht threadsicher ist, wird das Ergebnis zurückgegeben, wenn mehrere Threads gleichzeitig die Funktion formatDate aufrufen wird nicht den Erwartungen entsprechen. Wenn ThreadLocal zum Definieren threadspezifischer Objekte verwendet wird, lautet der optimierte Code wie folgt:

/** 本地日期格式 */private static final ThreadLocal<DateFormat> LOCAL_DATE_FORMAT = new ThreadLocal<DateFormat>() {    @Override
    protected DateFormat initialValue() {        return new SimpleDateFormat("yyyy-MM-dd");
    }
};/** 格式化日期函数 */public static String formatDate(Date date) {    return LOCAL_DATE_FORMAT.get().format(date);
}

Dies ist die Implementierungsmethode, bevor es eine Thread-sichere Datumsformatierungs-Toolklasse gibt. Nach JDK8 wird empfohlen, DateTimeFormatter anstelle von SimpleDateFormat zu verwenden, da SimpleDateFormat threadsicher und DateTimeFormatter threadsicher ist. Natürlich können Sie auch threadsichere Datumsformatierungsfunktionen von Drittanbietern verwenden, beispielsweise die DateFormatUtils-Toolklasse von Apache.

Hinweis: Bei ThreadLocal besteht ein gewisses Risiko für Speicherverluste. Versuchen Sie, die Remove-Funktion aufzurufen, um die Daten vor dem Ende des Geschäftscodes zu löschen.

Das obige ist der detaillierte Inhalt vonWie Java ThreadLocal verwendet, um threadspezifische Objekte zu speichern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen