<Type = "text/webpage effects"> function windowTitle () {if (location. href. indexOf ('IS-external = true') =-1) {parent.doc ument. title = "Lock (Java Platform SE 6 )";}}
The Lock implementation provides a wider range of Lock operations than the synchronized method and statement. This implementation allows a more flexible structure, can have very different attributes, and can support multiple related Condition objects.
A lock is a tool that controls multiple threads to access shared resources. Generally, a lock provides exclusive access to shared resources. Only one thread can obtain the lock at a time. All access to shared resources must first obtain the lock. However, some locks may allow concurrent access to shared resources, such as ReadWriteLock read locks.
The use of the synchronized method or statement provides access to the implicit monitor lock related to each object, but forces all lock acquisition and release to appear in a block structure: when multiple locks are obtained, they must be released in reverse order, and all locks must be released within the same lexical range as when all locks are obtained.
Although synchronized methods and the range mechanism of statements make it much easier to use the monitor lock programming, it also helps avoid many common programming errors related to locks, but sometimes the lock needs to be used in a more flexible way. For example, some algorithms that traverse the data results of concurrent access require the use of "hand-over-hand" or "chain locking": obtain the lock of node A, and then obtain the lock of node B, release A and obtain C, release B and obtain D, and so on. The implementation of the Lock interface allows the Lock to be acquired and released in different ranges of effect, and allows the acquisition and release of multiple locks in any order, thus supporting the use of this technology.
As flexibility increases, it also brings more responsibilities. If you do not use the block structure lock, the lock Auto release function will be lost when you use the synchronized method and statement. In most cases, use the following statement:
Lock l = ...;
L. lock ();
Try {
// Access the resource protected by this lock
} Finally {
L. unlock ();
}
When locking or unlocking occurs in different scopes, you must be careful to ensure that all code executed when the lock is maintained is protected by try-finally or try-catch, to ensure that the lock is released when necessary.
The Lock implementation provides other functions not available in the synchronized method and statement, including a non-block structure get Lock attempt (tryLock ()) lockInterruptibly () and tryLock (long, TimeUnit )).
The Lock class also provides behaviors and semantics that are completely different from the implicit monitor Lock, such as guaranteed sorting, non-reentrant usage, or deadlock detection. If an implementation provides such special semantics, the implementation must record these semantics.
Note that the Lock instance is only a common object and can be used as the target in the synchronized statement. There is no special relationship between obtaining the monitor Lock of the lock instance and calling any Lock () method of the instance. To avoid confusion, we recommend that you never use the Lock instance in this way except for its own implementation.
Unless otherwise specified, passing a null value for any parameter will throw NullPointerException.
Memory synchronization
All Lock implementations must implement The same Memory synchronization semantics as The built-in monitor Lock, as described in The Java Language Specification, Third Edition (17.4 Memory Model:
A successful lock operation has the same memory synchronization effect as a successful Lock operation.
Successful unlock operations have the same memory synchronization effect as successful Unlock operations.
No memory synchronization effect is required for unsuccessful locking and unlocking operations and re-locking/unlocking operations.
Implementation considerations
The three types of lock acquisition (can be interrupted, non-interrupted, and scheduled) may vary in terms of performance features, sorting guarantee, or other implementation quality. In addition, given Lock classes may not be able to interrupt the ability to acquire ongoing locks. Therefore, it is not required to define the same guarantee or semantics for all three forms of lock acquisition, nor to require it to support the suspension of the ongoing lock acquisition. Implementation must clearly record the semantics and guarantees provided by each locking method. You must also comply with the interrupt semantics defined in this interface to support lock acquisition interruption: fully support interruption, or only support interruption when entering the method.
As interruption usually means cancellation, and usually seldom checks for interruption, the implementation may prefer to respond to an interruption compared with normal method responses. This is true even if the interrupt that occurs after another operation may release the thread lock. Implementation should record this behavior
File: connector Sor. java
Import javax. persistence. CascadeType;
Import javax. persistence. Entity;
Import javax. persistence. Id;
Import javax. persistence. ManyToOne;
Import javax. persistence. Version;
@ Entity
Public class extends Sor {
@ Id private int id;
Private String name;
Private long salary;
Private int vacationDays;
@ Version private int version;
@ ManyToOne (cascade = {CascadeType. REFRESH })
Private volume Sor manager;
Public int getId (){
Return id;
}
Public void setId (int id ){
This. id = id;
}
Public String getName (){
Return name;
}
Public void setName (String name ){
This. name = name;
}
Public long getSalary (){
Return salary;
}
Public void setSalary (long salary ){
This. salary = salary;
}
Public int getVacationDays (){
Return vacationDays;
}
Public void setVacationDays (int vacation ){
This. vacationDays = vacation;
}
Public encryption Sor getManager (){
Return manager;
}
Public void setManager (volume Sor manager ){
This. manager = manager;
}
Public String toString (){
Return "pointer Sor id:" + getId () + "name:" + getName () +
"Vacation:" + getVacationDays () + "salary:" + getSalary ();
}
}
File: ProfessorService. java
Import javax. persistence. EntityManager;
Import javax. persistence. LockModeType;
Import javax. persistence. Query;
Public class ProfessorService {
Protected EntityManager em;
Public ProfessorService (EntityManager em ){
This. em = em;
}
Public void lockAllProfessors (){
Query query = em. createQuery ("SELECT e FROM foreign Sor e ");
For (Object employee: query. getResultList ()){
Em. lock (employee, LockModeType. WRITE );
}
}
}
File: JPAUtil. java
Import java. io. Reader;
Import java. SQL. Connection;
Import java. SQL. DriverManager;
Import java. SQL. ResultSet;
Import java. SQL. ResultSetMetaData;
Import java. SQL. Statement;
Public class JPAUtil {
Statement st;
Public JPAUtil () throws Exception {
Class. forName ("org. hsqldb. jdbcDriver ");
System. out. println ("Driver Loaded .");
String url = "jdbc: hsqldb: data/tutorial ";
Connection conn = DriverManager. getConnection (url, "sa ","");
System. out. println ("Got Connection .");
St = conn. createStatement ();
}
Public void executeSQLCommand (String SQL) throws Exception {
St.exe cuteUpdate (SQL );
}
Public void checkData (String SQL) throws Exception {
ResultSet rs = st.exe cuteQuery (SQL );
ResultSetMetaData metadata = rs. getMetaData ();
For (int I = 0; I <metadata. getColumnCount (); I ++ ){
System. out. print ("t" + metadata. getColumnLabel (I + 1 ));
}
System. out. println ("n ----------------------------------");
While (rs. next ()){
For (int I = 0; I <metadata. getColumnCount (); I ++ ){
Object value = rs. getObject (I + 1 );
If (value = null ){
System. out. print ("t ");
} Else {
System. out. print ("t" + value. toString (). trim ());
}
}
System. out. println ("");
}
}
}
File: Main. java
Import javax. persistence. EntityManager;
Import javax. persistence. EntityManagerFactory;
Import javax. persistence. Persistence;
Public class Main {
Public static void main (String [] a) throws Exception {
JPAUtil util = new JPAUtil ();
EntityManagerFactory emf = Persistence. createEntityManagerFactory ("ProfessorService ");
EntityManager em = emf. createEntityManager ();
ProfessorService service = new ProfessorService (em );
Em. getTransaction (). begin ();
Service. lockAllProfessors ();
Util. checkData ("select * from foreign Sor ");
Em. getTransaction (). commit ();
Em. close ();
Emf. close ();
}
}
File: persistence. xml
<Persistence xmlns = "http://java.sun.com/xml/ns/persistence"
Xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
Xsi: schemaLocation = "http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence" version = "1.0">
<Persistence-unit name = "JPAService" transaction-type = "RESOURCE_LOCAL">
<Properties>
<Property name = "hibernate. dialect" value = "org. hibernate. dialect. HSQLDialect"/>
<Property name = "hibernate. hbm2ddl. auto" value = "update"/>
<Property name = "hibernate. connection. driver_class" value = "org. hsqldb. jdbcDriver"/>
<Property name = "hibernate. connection. username" value = "sa"/>
<Property name = "hibernate. connection. password" value = ""/>
<Property name = "hibernate. connection. url" value = "jdbc: hsqldb: data/tutorial"/>
</Properties>
</Persistence-unit>
</Persistence>