1. Lock lock and condition conditions
3 Implementation classes for the lock interface:
Reentrantlock,reentrantreadwritelock.readlock and Reentrantreadwritelock.writelock. Lock must be displayed by creating, locking and releasing, locking and releasing locks in the same way:
//默认使用非公平锁,如果要使用公平锁,需要传入参数true locknew ReentrantLock();//........ lock.lock(); try { //更新对象的状态 //捕获异常,必要时恢复到原来的不变约束 //如果有return语句,放在这里 finally { lock.unlock(); //锁必须在finally块中释放 }
1. Wait for interruptible: When the thread holding the lock does not release the lock for a long time, the waiting thread can choose to discard the wait and instead handle the other things, which is useful for processing a synchronization block that has a very long execution time. While waiting for the mutex generated by the synchronized, it will always block, can not be interrupted.
2, can achieve a fair lock: When multiple threads are waiting for the same lock, they must be queued in the order in which they are requested, while non-fair locks do not guarantee this, and any thread that waits for a lock has a chance to acquire a lock when the lock is released. Synchronized locks are not fair when locked, Reentrantlock is also an unfair lock by default, but you can require a fair lock by constructing method Reentrantlock (ture).
3. Locks can bind multiple conditions: Reentrantlock objects can bind multiple condition objects (condition variables) at the same time, and in synchronized, The Wait () and notify () or Notifyall () methods of the lock object can implement an implied condition, and reentrantlock only needs to call the Newcondition () method multiple times. And we can also bind the condition object to determine which threads are being notified by the current thread (that is, other threads that are bound to the condition object).
Reetrantlock has two types of locks: ignoring interrupt locks and responding to interrupt locks. Ignoring an interrupt lock, like a mutex implemented by the synchronized, cannot respond to interrupts, while a response interrupt lock can respond to interrupts.
If a thread A is executing the code in the lock, and a second thread B is waiting to acquire the lock, it may be because the wait is too long, the threads B does not want to wait, and wants to deal with something else first, we can let it break itself or interrupt it in another thread, if Reetrantlock provides a ignore interrupt lock at this time, It does not bother with the interrupt, but instead lets thread B continue to wait, and if at this point the Reetrantlock provides a response interrupt lock, then it will handle the interrupt and let thread B discard the wait and turn to other things.
When 中断
you wait on a mutex with synchronized, it doesn't work, and the thread still waits
reentrantlock lock = new reentrantlock (); //..... lock . lockinterruptibly (); //get response interrupt lock try {//update the state of the object //catch exception, revert to the original immutable constraint if necessary //if there is a return statement, put it here } finally {lock . Unlock (); //lock must be released in the Finally Block }
- Conditional variables for inter-threading collaboration
After Java 5, we can use the Reentrantlock lock with the await () and signal () or Signalall () methods on the condition object to enable inter-thread collaboration. On the Reentrantlock object Newcondition () can get a condition object that can be suspended by an await () method on the condition to suspend a task (thread), by signal () on the condition to notify the task, either wake up a task, or call Signalall () to wake up all the tasks that are suspended on this condition. In addition, if a fair lock is used, all tasks associated with the condition of the Signalall () will acquire the lock in the form of a FIFO queue, and if no fair lock is used, the task of acquiring the lock is random, so that we can better control the order in which the task in the await state acquires the lock. Signalall () is a more secure way than Notifyall (). In addition, it can specify a task that wakes up a binding with its own condition object.
Class info{//Define Information classes PrivateString name ="Name";//define the Name property, in order to distinguish it from the Name property of the following set PrivateString content ="Content";//Define the Content property in order to distinguish it from the content property of the set below PrivateBoolean flag =true;//Set flag bit, first production at initial PrivateLockLock=NewReentrantlock ();PrivateCondition Condition =Lock. Newcondition ();//produce a condition object Public void Set(String name,string content) {Lock.Lock();Try{ while(!flag) {condition.await() ; } This. SetName (name);//Set nameThread.Sleep ( -) ; This. setcontent (content);//Set contentFlag =false;//Change the flag to indicate that it can be taken awayCondition.signalall (); }Catch(Interruptedexception e) {E.printstacktrace (); }finally{Lock. Unlock (); } } Public void Get(){Lock.Lock();Try{ while(flag) {condition.await() ; } thread.sleep ( -) ; System. out. println ( This. GetName () +" --"+ This. getcontent ()); Flag =true;//Change the flag to indicate that it can be producedCondition.signalall (); }Catch(Interruptedexception e) {E.printstacktrace (); }finally{Lock. Unlock (); } } Public void SetName(String name) { This. name = name; } Public void setcontent(String content) { This. Content = content; } PublicStringGetName(){return This. Name; } PublicStringgetcontent(){return This. Content; }} class Producer implements runnable{//multithreading via runnable PrivateInfo info =NULL;//Save Info Reference Public Producer(Info info) { This. info = info; } Public void Run() {Boolean flag =true;//define marker bit for(intI=0;i<Ten; i++) {if(flag) { This. info.Set("Name--1","Content--1") ;//Set nameFlag =false; }Else{ This. info.Set("Name--2","Content--2") ;//Set nameFlag =true; }}}} class Consumer implements runnable{PrivateInfo info =NULL; Public Consumer(Info info) { This. info = info; } Public void Run(){ for(intI=0;i<Ten; i++) { This. info.Get() ; } } } Public classthreadcasedemo{ Public Static void Main(String args[]) {Info info =NewInfo ();//Instantiate Info ObjectProducer Pro =NewProducer (info);//producerConsumer con =NewConsumer (info);//Consumer NewThread (PRO). Start ();//starts the producer thread and then starts the consumer thread Try{Thread.Sleep ( -) ; }Catch(Interruptedexception e) {E.printstacktrace (); }NewThread (Con). Start (); } }
- Read/write Lock
The mutex acquired by synchronized is not only an exclusive read-write operation, write operation, but also a mutual-reading operation, while the read operation will not bring the data competition, so the read-read operation is also mutually exclusive, will degrade performance. A read-write lock is provided in Java 5, which separates read and write locks, making read-read operations not mutually exclusive.
new ReentrantReadWriteLock(); rwl.writeLock().lock() //获取写锁 rwl.readLock().lock() //获取读锁
A read lock is used to lock the read operation, and a write lock is used to lock the write operation, so that the write and write operations are mutually exclusive, and the read and write operations are mutually exclusive, but read and read operations are not mutually exclusive.
2. Blocking queues
Blockingqueue has multiple implementation classes: Arrayblockingqueue, Delayqueue, Linkedblockingqueue, Priorityblockingqueue, Synchronousqueue, etc.
- Arrayblockingqueue
It implements a bounded queue, and when the queue is full, it blocks the wait until there are elements out of the queue and subsequent elements can be queued.
Public classblockingqueuetest{ Public Static void Main(string[] args) throws Interruptedexception {blockingqueue<string> Bqueue =NewArrayblockingqueue<string> ( -); for(inti =0; I < -; i++) {//Add the specified element to this queueBqueue.put ("add Element"+ i);//Will blockSystem. out. println ("added elements to the blocking queue:"+ i); } System. out. println ("The program ends at this run and is about to exit----"); } }
3. Cyclicbarrier
Cyclicbarrier is also a new feature added in Java 5, which needs to be imported into Java.util.concurrent.CylicBarrier.
It works in situations where you want to create a set of tasks that perform the work concurrently, and that the other task is blocked until the end of the execution of the set of tasks, until all the group tasks have been completed and the task is executed.
Public class cyclicbarriertest { Public Static void Main(string[] args) {//Create Cyclicbarrier object, //and set the concurrency task to execute a set of 5 threads before performing the Maintask taskCyclicbarrier cb =NewCyclicbarrier (5,NewMaintask ());NewSubTask ("A", CB). Start ();NewSubTask ("B", CB). Start ();NewSubTask ("C", CB). Start ();NewSubTask ("D", CB). Start ();NewSubTask ("E", CB). Start (); } }/** * Last task performed * /Class Maintask implements Runnable { Public void Run() {System.out.println ("...... Finally the final mission is to be carried out ... "); } }/** * A set of concurrent tasks * /Class SubTask extends Thread {PrivateString name;PrivateCyclicbarrier CB; SubTask (String name, Cyclicbarrier CB) { This. name = name; This. cb = CB; } Public void Run() {System.out.println (the [concurrent tasks]+ name +"] Start execution"); for(inti =0; I <999999; i++);//Simulate time-consuming tasksSystem.out.println (the [concurrent tasks]+ name +"] Start execution, notify the barrier);Try{//To notify the obstacle when each task is performedCb.await (); }Catch(Interruptedexception e) {E.printstacktrace (); }Catch(Brokenbarrierexception e) {E.printstacktrace (); } } }
4. Semaphore Semaphore
In the operating system, the semaphore is a very important concept, it plays a very important role in the cooperation between the control process, through the different operation of the signal volume, can be mutually exclusive and synchronization between processes. Of course it can also be used for multi-threaded control, and we can completely implement synchronized, wait, and notify mechanisms similar to Java by using semaphores.
The semaphore semaphore in Java and the bundle is actually a count semaphore, conceptually, it maintains a set of licenses, which is very important for controlling the consumption and recovery of certain resources. Semaphore can control the number of tasks that a resource is accessed concurrently, and it obtains a license through acquire (), releasing a license with release (). If the number of concurrently accessed tasks is full, the other acquire tasks go into a wait state until a task is removed before it can be licensed.
Public classsemaphoretest{ Public Static void Main(string[] args) {//Adopt new features to start and manage threads--internal use of thread poolExecutorservice exec = Executors.newcachedthreadpool ();//Allow only 5 threads to access simultaneouslyFinal Semaphore semp =NewSemaphore (5);//Simulation of 10 Client Access for(intindex =0; Index <Ten; index++) {Finalintnum = index; Runnable Run =NewRunnable () { Public void Run() {Try{//Get permissionSemp.acquire (); System. out. println ("Threads"+ Thread.CurrentThread (). GetName () +"Get permission:"+ num);//Simulate time-consuming tasks for(inti =0; I <999999; i++);//Release licenseSemp.release (); System. out. println ("Threads"+ Thread.CurrentThread (). GetName () +"Release License:"+ num); System. out. println ("Number of tasks currently allowed to enter:"+ semp.availablepermits ()); }Catch(Interruptedexception e) {E.printstacktrace (); } } }; Exec.execute (run); }//close thread poolExec.shutdown (); } }
Semaphore allow concurrent access to the number of tasks has been 5, of course, it is also easy to see that the semaphore is only the number of concurrent access to the resources of the task to monitor, but not to ensure that the thread security, so when access, you have to control the thread security access.
5. Use of Countdownlatch
Thread Rollup (3)