Thread synchronization and communication

Thread synchronization and communication
in Java volatile, synchronized and the final realization of visibility.
  In Java synchronized and a lock, unlock operation guarantee atomicity.
   Java language provides volatile and synchronized two keywords to ensure the orderly operation between threads of


a.
Synchronized implement thread synchronization

synchonzied synchronization mechanism to synchronize multiple threads to concurrently access the same resource control .
The main purpose is to ensure the synchronization of data sharing between multiple threads. Synchronization will bring significant performance overhead , 
so it should be fine-grained synchronization (using different elements of different objects in the lock, rather than the entire object lock).
If synchronization is used properly, bring performance overhead is negligible. Synchronous real risk is that the complexity and resources could undermine the security, rather than performance.

Since each object of the java has a built-in lock, when using this keyword modification methods, built-in locks protect the entire method.
Before calling this method, you need to get the built-in lock, otherwise it is blocked.

Note: the synchronized keyword static methods can also be modified, if the static method call at this time, it will lock the entire class.
  Note: Synchronization is a high-cost operation, and therefore should be minimized sync.
It is usually not necessary to synchronize the entire method synchronized code block synchronization using the key code.

Synchronization method: a method to increase after the synchronized modifier can make it a synchronization method,
this method can be static and non-static methods,
but can not be abstract method of an abstract class, nor is the interface method interface.
 1      new Thread() {
 2             @Override
 3             public void run() {
 4                 synchronized (this) {
 5                     for (int i = 'a'; i <= 'g'; i++) {
 6                         System.out.print((char) i);
 7                     }
 8                 }
 9             }
10         }.start();


II. Use special domain variable volatile implement thread synchronization
Variables need to be synchronized plus volatile
Private volatile int the Account = 100;

volatile keyword provides a mechanism for lock-free access to the domain variable
    b using a volatile modification domain is equivalent to tell the virtual machine to the domain might be another thread updates.
    C. Thus the recalculation per domain, instead of using the value in the register 
    D. volatile operation does not provide any atom, it can not be used to modify the final type of variable

volatile variables, it will have a visibility .
volatile variables are not allowed inside thread and reorder buffer that directly modify the memory .
So the other threads are visible.
But note here a problem, volatile only let him be content with a modified visibility, but can not guarantee that it is atomic.
For example, volatile int a = 0; a ++ after a operation; this variable has a visibility, but still a ++ is a non-atomic operation,
that is, this operation also exists thread-safety issues. 


Three
.
Use reentrant locks for thread synchronization
      ReentrantLock() : 创建一个ReentrantLock实例
lock() : 获得锁
unlock() : 释放锁

可重入锁
ReentrantLock是可以重入的锁,当一个线程获取锁时,还可以接着重复获取多次。
ReentrantLock需要手动加锁和解锁,且解锁的操作尽量要放在finally代码块中,保证线程正确释放锁。
ReentrantLock和synchronized都是可重入的。
synchronized因为可重入因此可以放在被递归执行的方法上,且不用担心线程最后能否正确释放锁
ReentrantLock在重入时要却确保重复获取锁的次数必须和重复释放锁的次数一样,否则可能导致其他线程无法获得该锁。

公平锁

是指当锁可用时,在锁上等待时间最长的线程将获得锁的使用权

而非公平锁则随机分配这种使用权。

和synchronized一样,默认的ReentrantLock实现是非公平锁,因为相比公平锁,非公平锁性能更好。

当然公平锁能防止饥饿,某些情况下也很有用。

在创建ReentrantLock的时候通过传进参数true创建公平锁,如果传入的是false或没传参数则创建的是非公平锁

ReentrantLock lock = new ReentrantLock(true);
 
 1 public class ReentrantLockTest {
 2 
 3     public static void main(String[] args) throws InterruptedException {
 4 
 5         ReentrantLock lock = new ReentrantLock();
 6 
 7         //需要同步的内容在lock()与unlock()之间
 8         for (int i = 1; i <= 3; i++) {
 9             lock.lock();
10         }
11 
12         for (int i = 1; i <= 3; i++) {
13             try {
14 
15             } finally {
16                 lock.unlock();
17             }
18         }
19     }
20 }
 

四.
wait和notify实现线程间通信

wait()
:使一个线程处于等待状态,并且释放所持有的对象的lock。

sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,
调用此方法要捕捉InterruptedException异常。

并不会释放锁
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,
并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
 
 1        /**
 2          * 线程交替打印案例
 3          * ab1cd2ef3
 4          */
 5         //对象锁
 6         Object obj = new Object();
 7         new Thread() {
 8             @Override
 9             public void run() {
10                 //同步
11                 synchronized (obj) {
12                     int a = 2;
13                     for (int i = 'a'; i <= 'g'; i++) {
14                         if (a == 0) {
15                             try {
16                                 a = 2;
17                                 //把别人唤醒,自己再睡
18                                 obj.notifyAll();
19                                 obj.wait();
20                             } catch (InterruptedException e) {
21                                 e.printStackTrace();
22                             }
23                         }
24                         System.out.print((char) i);
25                         a--;
26                     }
27                 }
28             }
29         }.start();
30 
31         new Thread(new Runnable() {
32             @Override
33             public void run() {
34                 synchronized (obj) {
35                     for (int i = 1; i <= 10; i++) {
36                         System.out.print(i);
37                         try {
38                             //把别人唤醒,自己再睡
39                             obj.notifyAll();
40                             obj.wait();
41                         } catch (InterruptedException e) {
42                             e.printStackTrace();
43                         }
44                     }
45                 }
46             }
47         }).start();

Guess you like

Origin www.cnblogs.com/loveer/p/11287915.html