This is the third article on ThreadLocal. This article will take a look at some of the major Java open source frameworks, analyze how they use ThreadLocal from source code, and learn their design ideas.

You can go to Github, search for the project, and then search for the relevant class within the project to see the source code.

Quartz

Quartz is a well-known open source task scheduling system.

The source code is Quartz’s SimpleSemaphore class. It’s an implementation of a semaphore, which in the producer-consumer model represents how many items in the queue need to be processed.

In the semaphore model there is a “wait” operation. When the consumer finished consumption, will polling and waiting. SimpleSemaphore has a method for obtaining locks called obtainLock(), which we’ll look at inside:


In line 92, the while loop is for polling. Locks in the while is a HashSet, and true means that the lock is being held by another thread, so the current thread has to wait.

We see that in line 86 of the outer while loop, there is a judgment that actually uses ThreadLocal.


What does this outer layer of judgment do? Determine if the current thread already holds the lock. If it holds, it jumps to the end of return true. Because of the same thread, multiple program fragments may call this lock method.

As you can see, using ThreadLocal makes it very efficient to determine the state of the current thread. You can quickly detect whether the current thread has acquired the lock, avoiding subsequent lock detection and contention.

Mybatis

Mybatis need not say more, engage in Java should have heard or used. What we are going to introduce today is its SQlssession Manager.

Mybatis is a persistence framework. Persistence frameworks, of course, face the problem of transactions. Our databases (such as MySQL) can guarantee local transactions, but they must be on the same connection.

The application using MyBatis may access the database in multiple program fragments and do some add, delete, change and check operations. They might need to be in the same transaction.

For example, after we change the order status, we might also need to change the credits, which should be in the same transaction.

Mybatis uses SqlSessionManager to ensure that all connections from the same thread are always the same. How does it do it? This is simply an internal ThreadLocal.

All connections are then created and fetched using the ThreadLocal variable’s GET /set methods.

private final ThreadLocal<SqlSession> localSqlSession = new ThreadLocal<>();


// Create a connection
public void startManagedSession(a) {
 this.localSqlSession.set(openSession()); }  / / remove connections @Override public Connection getConnection(a) {  final SqlSession sqlSession = localSqlSession.get();  if (sqlSession == null) {  throw new SqlSessionException("Error: Cannot get connection. No managed session is started.");  }  return sqlSession.getConnection(); } Copy the code

conclusion

ThreadLocal is actually quite simple to use, which is why ThreadLocal was designed.

With ThreadLocal, thread state can be stored, making it easy for multiple program fragments to access data from the current thread without affecting other threads or requiring locking synchronization.

Therefore, using ThreadLocal can “avoid” some of the multithreading problems and develop secure and efficient applications.

About the author

I’m Yasin, a good-looking and interesting programmer.

Wechat public number: made up a process

Personal website: https://yasinshaw.com

Pay attention to my public number, grow up with me ~

The public,