概念(重要):Java 类可能有很多个对象,但只有一个Class对象
形式1:synchronized 加载 static 方法上
形式2:synchronized (*.class) 代码块
本质:所以所谓的类锁,不过是Class对象的锁而已。
用法和效果:类锁只能在同一时刻被一个对象拥有。
形式1:synchronized 加载 static 方法上的案例:
/**
* @author sxylml
* @Date : 2019/2/26 10:04
* @Description: 类锁的一种形式,static 形式
*/
public class SynchronizedClassStatic implements Runnable {
static Runnable instatnce1 = new SynchronizedClassStatic();
static Runnable instatnce2 = new SynchronizedClassStatic();
public synchronized void method() {
System.out.println("我是类锁的第一种形式:static 形式,我叫:" + Thread.currentThread().getName());
try {
System.out.println(Thread.currentThread().getName() + "休眠3秒");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 运行结束");
}
@Override
public void run() {
method();
}
public static void main(String[] args) {
Long startTime = System.currentTimeMillis();
Thread t1 = new Thread(instatnce1);
Thread t2 = new Thread(instatnce2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
Long endTime = System.currentTimeMillis();
System.out.println("finished 耗时"+(endTime-startTime));
}
}
image.png
加上static
/**
* @author sxylml
* @Date : 2019/2/26 10:04
* @Description: 类锁的一种形式,static 形式
*/
public class SynchronizedClassStatic implements Runnable {
static Runnable instatnce1 = new SynchronizedClassStatic();
static Runnable instatnce2 = new SynchronizedClassStatic();
public static synchronized void method() {
System.out.println("我是类锁的第一种形式:static 形式,我叫:" + Thread.currentThread().getName());
try {
System.out.println(Thread.currentThread().getName() + "休眠3秒");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 运行结束");
}
@Override
public void run() {
method();
}
public static void main(String[] args) {
Long startTime = System.currentTimeMillis();
Thread t1 = new Thread(instatnce1);
Thread t2 = new Thread(instatnce2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
Long endTime = System.currentTimeMillis();
System.out.println("finished 耗时"+(endTime-startTime));
}
}
image.png
使用2种对象锁,2种类锁解决问题:
package com.cap1.synchronizedsdemo;
/**
* @author sxylml
* @Date : 2019/2/25 16:47
* @Description:
* 消失的请求
* 不采用并发控制,执行结果就不是我们所预计的效果。
* <p>
* 原因:count ++ 看上去是一个操作,实际上包含三个动作
* 1:读取count
* 2: 将count +1
* 3:将count 的值写入内存
*/
public class DisappearRequest implements Runnable {
static DisappearRequest instance = new DisappearRequest();
static int count = 0;
public static void main(String[] args) {
Thread thread1 = new Thread(instance);
Thread thread2 = new Thread(instance);
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
System.out.println(count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// /**
// * 1 使用 synchronized 代码块方式
// */
// @Override
// public void run() {
// for (int i = 0; i < 100000; i++) {
//// 不加锁运行结果基本都是小于 200000
// synchronized (this){
// count++;
// }
// }
// }
// /**
// * 2 使用 1synchronized 修饰普通方法
// */
// @Override
// public synchronized void run() {
// for (int i = 0; i < 100000; i++) {
// count++;
// }
// }
// /**
// * 3 类锁: 使用 1synchronized 修饰普通方法
// */
// @Override
// public synchronized void run() {
// for (int i = 0; i < 100000; i++) {
// synchronized (DisappearRequest.class) {
// count++;
// }
// }
// }
/**
* 四 类锁:修饰 static 方法
*/
public synchronized static void method(){
for (int i = 0; i < 100000; i++) {
count++;
}
}
@Override
public void run() {
method();
}
}
运行结果就不会少咯。
网友评论