synchronized
synchronized这个关键字可以修饰方法也可以修饰代码块,在修饰方法时与对this加锁效果是一样的
synchronized(this){
//被加锁内容...
}
这是对该实体对象的锁定
synchronized(Test.class){
//被加锁内容...
}
这是对Test类的所有实体对象进行锁定。
static
被static修饰的方法是类方法,也就意味着所有该类的实体对象访问这个方法都会去到同一块地方。
static与synchronized同时修饰一个方法
static与synchronized同时修饰一个方法也就是对该类所有实例访问的同一块内存进行加锁,自然锁的是该类的全部实例对象,效果与synchronized(Test.class){...}一样。接下来亲自测试一下:
使用四个不同的线程和实例对象去访问static与synchronized联合修饰的方法
public class StaticAndsynchronized {
public static void main(String[] args) {
StaticAndsynchronized test1 = new StaticAndsynchronized();
StaticAndsynchronized test2 = new StaticAndsynchronized();
StaticAndsynchronized test3= new StaticAndsynchronized();
StaticAndsynchronized test4= new StaticAndsynchronized();
new Thread(()->{
test1.task2();
},"线程A").start();
new Thread(()->{
test2.task2();
},"线程B").start();
new Thread(()->{
test3.task2();
},"线程C").start();
new Thread(()->{
test4.task2();
},"线程D").start();
}
//普通的同步
public synchronized void task1(){
while(true){
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":执行了Taks1...");
}
}
//static 与 synchronized 联合使用
public static void task2(){
synchronized(StaticAndsynchronized.class){
while(true){
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":执行了Taks2...");
}
}
}
}
执行结果:只有一个线程在一直执行
去访问普通的synchronized 方法运行结果: 四个线程交替执行
总结:
synchronized 与 static synchronized 的区别就是锁定的对象不同,单加synchronized 锁定的是单个实体对象, static synchronized联用锁定的是该类下的所有实体对象。