早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。
Threadlocal变量
ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
从线程的角度看,目标变量就像是线程的本地变量,这也是类名中“Local”所要表达的意思。
线程局部变量并不是Java的新发明,很多语言(如IBM IBM XL FORTRAN)在语法层面就提供线程局部变量。在Java中没有提供在语言级支持,而是变相地通过ThreadLocal的类提供支持。
所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。
ThreadLocal的接口方法
ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:
void set(Object value)
设置当前线程的线程局部变量的值。
public Object get()
该方法返回当前线程所对应的线程局部变量。
public void remove()
将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
protected Object initialValue()
返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。
值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal<T>。API方法也相应进行了调整,新版本的API方法分别是void set(T value)、T get()以及T initialValue()。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中定义了一个ThreadLocalMap,每一个Tread中都有一个该类型的变量——threadLocals——用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。
os.time() <== 返回当前系统的日历时间
os.date() <== 返回本地化的时间字符串,这里是"11/28/08 17:23:37"
os.date("%x", os.time()) <== 返回自定义格式化时间字符串(完整的格式化参数),这里是"11/28/08"
os.clock() <== 返回执行该程序CPU花去的时钟秒数,这里是1156.726
附录
完整的格式化参数
这些时间输出的字符串表示是经过本地化的。所以如果是在巴西(葡萄牙语系),"%B" 得到的就是 "setembro"(译者按:大概是葡萄牙语九月?),"%x" 得到的就是 "16/09/98"(月日次序不同)。标记的意义和显示实例总结如下表。实例的时间是在1998年九月16日,星期三,23:48:10。返回值为数字形式的还列出了它们的范围。(都是按照英语系的显示描述的,也比较简单,就不烦了)
%a abbreviated weekday name (e.g., Wed)
%A full weekday name (e.g., Wednesday)
%b abbreviated month name (e.g., Sep)
%B full month name (e.g., September)
%c date and time (e.g., 09/16/98 23:48:10)
%d day of the month (16) [01-31]
%H hour, using a 24-hour clock (23) [00-23]
%I hour, using a 12-hour clock (11) [01-12]
%M minute (48) [00-59]
%m month (09) [01-12]
%p either "am" or "pm" (pm)
%S second (10) [00-61]
%w weekday (3) [0-6 = Sunday-Saturday]
%x date (e.g., 09/16/98)
%X time (e.g., 23:48:10)
%Y full year (1998)
%y two-digit year (98) [00-99]
%% the character '%'
事实上如果不使用任何参数就调用date,就是以%c的形式输出。这样就是得到经过格式化的完整时间信息。
注意%x、%X和%c由所在地区和计算机系统的改变会发生变化。
如果该字符串要确定下来(例如确定为mm/dd/yyyy),可以使用明确的字符串格式方式(例如"%m/%d/%Y")。
1, 临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;
2, 持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;
3, 游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象;
× √
临时状态(Transient)
持久化状态(Persistent)
游离状态(Detached)
是否处于Session缓存中
×
√
×
数据库中是否有对应记录
×
√
√
游离状态的实例可以通过调用save()、persist()或者saveOrUpdate()方法进行持久化。
持久化实例可以通过调用 delete()变成脱管状态。通过get()或load()方法得到的实例都是持久化状态的。
脱管状态的实例可以通过调用 update()、saveOrUpdate()、lock()或者replicate()进行持久化。
Transient instances may be made persistent by calling
save(), persist() or saveOrUpdate(). Persistent instances may be made transient by calling delete(). Any instance returned by a
get() or load() method is persistent. Detached instances may be made persistent by calling
update(), saveOrUpdate(), lock() or replicate(). The state of a transient or detached instance may also be made persistent as a new persistent instance by calling
merge().
save() and persist() result in an SQL INSERT, delete() in an SQL
DELETE and update() or merge() in an SQL UPDATE. Changes to
persistent instances are detected at flush time and also result in an SQL
UPDATE. saveOrUpdate() and replicate() result in either an
INSERT or an UPDATE.
--------------------------------save
Serializable save(Object object)
描述:
Persist the given transient instance, first assigning a generated identifier. (Or using the current value of the identifier property if the assigned generator is used.) This operation cascades to(级联到) associated instances if the association is mapped with cascade="save-update"
参数:
object - a transient instance of a persistent class
返回:
the generated identifier
-------------
------------------------------update
void update(Object object)
描述:
Update the persistent instance with the identifier of the given detached instance. If there is a persistent instance with the same identifier, an exception is thrown. This operation cascades to(级联到) associated instances if the association is mapped with cascade="save-update"
参数:
object - a detached instance containing updated state
-------------
------------------------------flush
void flush()throws HibernateException
描述:
Force this session to flush. Must be called at the end of a unit of work, before committing the transaction and closing the session (depending on setFlushMode(FlushMode), Transaction.commit() calls this method). Flushing is the process of synchronizing the
underlying persistent store with persistable state held in memory.
抛出:
HibernateException - Indicates problems flushing the session or talking to the database.
--------------
------------------------------load
Object load(Class theClass,Serializable id)
描述:
Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists. This method might return a proxied instance that is initialized on-demand, when a non-identifier method is accessed.
You should not use this method to determine if an instance exists (use get() instead). Use this only to retrieve an instance that you assume exists, where non-existence would be an actual error.
参数:
theClass - a persistent class
id - a valid identifier of an existing persistent instance of the class
返回:
the persistent instance or proxy
---------------
------------------------------merge
Object merge(Object object)
描述:
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy
of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge"
The semantics(语义学) of this method are defined by JSR-220.
参数:
object - a detached instance with state to be copied
返回:
an updated persistent instance
---------------
------------------------------persist
void persist(Object object)
描述:
Make a transient instance persistent. This operation cascades to associated instances if the association is mapped with cascade="persist"
The semantics of this method are defined by JSR-220.
参数:
object - a transient instance to be made persistent
---------------
------------------------------delete
void delete(Object object)
描述:
Remove a persistent instance from the datastore. The argument may be an instance associated with the receiving Session or a transient instance with an identifier associated with existing persistent state. This operation cascades to associated instances if the
association is mapped with cascade="delete"
参数:
object - the instance to be removed
----------------
-----------------------------commit
void commit()
Commit(提交) this transaction. This might entail(需要) a number of things depending on the context:
a.If this transaction(事务) is the initiator(引爆器), Session.flush() the Session with which it is associated (unless Session is in FlushMode.MANUAL).
b.If this transaction is the initiator, commit the underlying transaction.
c.Coordinate(调整) various callbacks(回调函数)
抛出:
HibernateException - Indicates a problem committing the transaction.