Java中的每個對象都有一個與之關聯的內部鎖(Intrinsic lock). 這種鎖也稱為監視器(Monitor), 這種內部鎖是一種排他鎖,可以保障原子性,可見性與有序性。
內部鎖是通過synchronized關鍵字實現的.synchronized關鍵字修飾代碼塊,修飾該方法。
修飾代碼塊的語法:
synchronized( 對象鎖 ) {
同步代碼塊,可以在同步代碼塊中訪問共享數據
}
修飾實例方法就稱為同步實例方法
修飾靜態方法稱稱為同步靜態方法
package com.wkcto.intrinsiclock;
/**
* synchronized同步代碼塊
* this鎖對象
* Author: 老崔
*/
public class Test01 {
public static void main(String[] args) {
//創建兩個線程,分別調用mm()方法
//先創建Test01對象,通過對象名調用mm()方法
Test01 obj = new Test01();
new Thread(new Runnable() {
@Override
public void run() {
obj.mm(); //使用的鎖對象this就是obj對象
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
obj.mm(); //使用的鎖對象this也是obj對象
}
}).start();
}
//定義方法,打印100行字符串
public void mm(){
synchronized ( this ) { //經常使用this當前對象作為鎖對象
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " --> " + i);
}
}
}
}
package com.wkcto.intrinsiclock;
/**
* synchronized同步代碼塊
* 如果線程的鎖不同, 不能實現同步
* 想要同步必須使用同一個鎖對象
* Author: 老崔
*/
public class Test02 {
public static void main(String[] args) {
//創建兩個線程,分別調用mm()方法
//先創建Test01對象,通過對象名調用mm()方法
Test02 obj = new Test02();
Test02 obj2 = new Test02();
new Thread(new Runnable() {
@Override
public void run() {
obj.mm(); //使用的鎖對象this就是obj對象
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
obj2.mm(); //使用的鎖對象this也是obj2對象
}
}).start();
}
//定義方法,打印100行字符串
public void mm(){
synchronized ( this ) { //經常使用this當前對象作為鎖對象
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " --> " + i);
}
}
}
}
package com.wkcto.intrinsiclock;
/**
* synchronized同步代碼塊
* 使用一個常量對象作為鎖對象
* Author: 老崔
*/
public class Test03 {
public static void main(String[] args) {
//創建兩個線程,分別調用mm()方法
//先創建Test01對象,通過對象名調用mm()方法
Test03 obj = new Test03();
Test03 obj2 = new Test03();
new Thread(new Runnable() {
@Override
public void run() {
obj.mm(); //使用的鎖對象OBJ常量
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
obj2.mm(); //使用的鎖對象OBJ常量
}
}).start();
}
public static final Object OBJ = new Object(); //定義一個常量,
//定義方法,打印100行字符串
public void mm(){
synchronized ( OBJ ) { //使用一個常量對象作為鎖對象
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " --> " + i);
}
}
}
}
package com.wkcto.intrinsiclock;
/**
* synchronized同步代碼塊
* 使用一個常量對象作為鎖對象,不同方法中 的同步代碼塊也可以同步
* Author: 老崔
*/
public class Test04 {
public static void main(String[] args) {
//創建兩個線程,分別調用mm()方法
//先創建Test01對象,通過對象名調用mm()方法
Test04 obj = new Test04();
Test04 obj2 = new Test04();
new Thread(new Runnable() {
@Override
public void run() {
obj.mm(); //使用的鎖對象OBJ常量
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
obj2.mm(); //使用的鎖對象OBJ常量
}
}).start();
//第三個線程調用靜態方法
new Thread(new Runnable() {
@Override
public void run() {
sm(); //使用的鎖對象OBJ常量
}
}).start();
}
public static final Object OBJ = new Object(); //定義一個常量,
//定義方法,打印100行字符串
public void mm(){
synchronized ( OBJ ) { //使用一個常量對象作為鎖對象
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " --> " + i);
}
}
}
//定義方法,打印100行字符串
public static void sm(){
synchronized ( OBJ ) { //使用一個常量對象作為鎖對象
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " --> " + i);
}
}
}
}