概念(重要):Java 類可能有很多個對象,但只有一個Class對象
形式1:synchronized 加載 static 方法上
形式2:synchronized (*.class) 代碼塊
本質(zhì):所以所謂的類鎖,不過是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:
* 消失的請求
* 不采用并發(fā)控制誓军,執(zhí)行結果就不是我們所預計的效果。
* <p>
* 原因:count ++ 看上去是一個操作疲扎,實際上包含三個動作
* 1:讀取count
* 2: 將count +1
* 3:將count 的值寫入內(nèi)存
*/
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();
}
}
運行結果就不會少咯昵时。