synchronized的作用
- 保证可见性
- 可见性:一个线程对共享变量进行修改,另一个线程需要立即获取到被修改后的值
package com.synchionzed;
import java.util.concurrent.TimeUnit;
public class demo1 {
private static boolean flag=true;
private static Object object=new Object();
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
while(flag){
synchronized (object){}
}
}).start();
TimeUnit.SECONDS.sleep(2);
new Thread(()->{
flag=false;
System.out.println("falg被修改了");
}).start();
}
}
- 保证原子性
- 原子性:在一次或者多次操作中,要么所有的操作都执行并且不会受到其他元素的干扰而中断,要么所有的操作都不执行
package com.synchronized;
import com.练习.死锁.MyThread;
import java.util.ArrayList;
public class demo2
{
private static int number = 0;
private static Object object = new Object();
public static void main(String[] args) throws InterruptedException
{
Runnable runnable=()->
{
for(int i = 0;i < 1000;i++)
{
synchronized(object)
{
number++;
}
}
}
}
ArrayList<Thread> list = new ArrayList<>();
for(int i = 0; i < 5; i++)
{
Thread t = new Thread(runnable);
t.start();
list.add(t);
}
for(Thread thread : list)
{
thread.join();
}
System.out.println(number);
}
- 保证有序性
- 有序性:是程序中代码的执行顺序,java在编译时和运行时会对代码进行优化,会导程序最终的执行顺序不一定就是我们编写代码时的顺序
package com.xupt.dao;
import org.openjdk.jcstress.annotations.*;
import org.openjdk.jcstress.infra.results.I_Result;
@JCStressTest
@Outcome(id={"1","4"},expect= Expect.ACCEPTABLE,desc="ok")
@Outcome(id="0",expect = Expect.ACCEPTABLE_INTERESTING,desc = "danger")
@State
public class demo {
int num=0;
boolean ready=false;
private Object object=new Object();
@Actor
public void actor1(I_Result r){
synchronized (object) {
if (ready) {
r.r1 = num + num;
} else {
r.r1 = 1;
}
}
}
@Actor
public void actor2(I_Result r){
synchronized (object) {
num = 2;
ready = true;
}
}
}
特性
- 可重入性
- 可重入性:一个线程可以多次执行synchronized,重复获取同一把锁。
package com.synchionzed
public class demo3
{
public static void main(String[] args)
{
Resource resource = new Resource();
new Thread(()->{
resource.demo();
}).static();
new Thread(()->{
resource.demo();
}).static();
}
}
class Resource{
public void demo(){
synchronized (Resource.class){
System.out.println(Thread.currentThread().getName()+"进入了同步代码块1");
synchronized (Resource.class){
System.out.println(Thread.currentThread().getName()+"进图了同步代码块2");
}
}
}
}
- 不可中断特性
一个线程获得锁后,另一个线程想要获得锁,必须属于阻塞或等待状态,如果第一个线程不释放锁,另一个线程会一直阻塞或等待。
原理
- 反汇编(javap -v demo4.class)
