1.特殊域变量(volatile)实现线程同步,只能修饰类中变量上,不能为final修饰
a.volatile关键字为域变量的访问提供了一种免锁机制,
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量;
e.volatile保证了修改的可见性,一个线程对这个变量进行了修改,其他引用这个变量的线程,立即会获取到修改之后的值;
/**
*@Author Thomas 2019-11-26 15:01
* The world of programs is a wonderful world
*/
public class Main {
private volatile int count=100;
public int countT(int count1){
System.out.println("原值 "+Thread.currentThread().getName()+" "+count+" count="+count1);
count=count+count1;
System.out.println("新值 "+Thread.currentThread().getName()+" "+count+" count="+count1);
return count;
}
public static void main(String[] args) {
Main main=new Main();
new Thread(new Runnable() {
@Override
public void run() {
int count = main.countT(1);
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
int count = main.countT(3);
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
int count = main.countT(2);
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
int count = main.countT(5);
}
}).start();
}
}
加上关键字修饰之后,出现同步,未加关键字出现不同步的 情况
out:
原值 Thread-0 100 count=1
新值 Thread-0 101 count=1
原值 Thread-2 101 count=2
原值 Thread-1 101 count=3
新值 Thread-1 106 count=3
新值 Thread-2 103 count=2
原值 Thread-3 106 count=5
新值 Thread-3 111 count=5
2.线程之间的同步互斥,需要使用到关键字来保护需要同步的代码,
synchronized,要保证互斥的线程使用同一把锁,才可以实现互斥的效果,
作用到方法上,锁就是当前对象
作用到静态方法上,锁就是类,所有调用这个方法的方法,都是同步的
作用到代码块上,需要设置锁;
可以作用到静态代码块中
static {
synchronized (Main.class){
}
}
public void print(String name){
int len=name.length();
synchronized (this){
for (int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
方法是对象调用,锁要加同一个对象,也就是需要加同一把锁
public synchronized void print1(String name){
int len=name.length();
for (int i=0;i<len;i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
解释以下名词:重排序,自旋锁,偏向锁,轻量级锁,可重入锁,公平锁,非公平锁,乐观锁,悲观锁
重入锁(ReentrantLock)是一种递归无阻塞的同步机制。重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。在JAVA环境下 ReentrantLock 和synchronized 都是 可重入锁。
自旋锁,由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠是非常必要的,自旋锁的效率远高于互斥锁。如何旋转呢?何为自旋锁,就是如果发现锁定了,不是睡眠等待,而是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时 才能进入临界区。
偏向锁(Biased Locking)是Java6引入的一项多线程优化,它会偏向于第一个访问锁的线程,如果在运行过程中,同步锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,这种情况下,就会给线程加一个偏向锁。 如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线程会被挂起,JVM会消除它身上的偏向锁,将锁恢复到标准的轻量级锁。
轻量级锁是由偏向所升级来的,偏向锁运行在一个线程进入同步块的情况下,当第二个线程加入锁争用的时候,偏向锁就会升级为轻量级锁。
重入锁(ReentrantLock)是一种递归无阻塞的同步机制,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。 在JAVA环境下 ReentrantLock 和synchronized 都是 可重入锁。
公平锁,就是很公平,在并发环境中,每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规则从队列中取到自己
非公平锁比较粗鲁,上来就直接尝试占有锁,如果尝试失败,就再采用类似公平锁那种方式。
感谢作者提供 https://www.cnblogs.com/tison/p/8283233.html;