Java中的每個對象都有一個與之關(guān)聯(lián)的內(nèi)部鎖(Intrinsic lock). 這種鎖也稱為監(jiān)視器(Monitor), 這種內(nèi)部鎖是一種排他鎖,可以保障原子性,可見性與有序性。
內(nèi)部鎖是通過synchronized關(guān)鍵字實現(xiàn)的.synchronized關(guān)鍵字修飾代碼塊,修飾該方法。
修飾代碼塊的語法:
synchronized( 對象鎖 ) {
同步代碼塊,可以在同步代碼塊中訪問共享數(shù)據(jù)
}
修飾實例方法就稱為同步實例方法
修飾靜態(tài)方法稱稱為同步靜態(tài)方法
package com.wkcto.intrinsiclock;
/**
* synchronized同步代碼塊
* this鎖對象
* Author: 老崔
*/
public class Test01 {
public static void main(String[] args) {
//創(chuàng)建兩個線程,分別調(diào)用mm()方法
//先創(chuàng)建Test01對象,通過對象名調(diào)用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 ) { //經(jīng)常使用this當(dāng)前對象作為鎖對象
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " --> " + i);
}
}
}
}
package com.wkcto.intrinsiclock;
/**
* synchronized同步代碼塊
* 如果線程的鎖不同, 不能實現(xiàn)同步
* 想要同步必須使用同一個鎖對象
* Author: 老崔
*/
public class Test02 {
public static void main(String[] args) {
//創(chuàng)建兩個線程,分別調(diào)用mm()方法
//先創(chuàng)建Test01對象,通過對象名調(diào)用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 ) { //經(jīng)常使用this當(dāng)前對象作為鎖對象
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) {
//創(chuàng)建兩個線程,分別調(diào)用mm()方法
//先創(chuàng)建Test01對象,通過對象名調(diào)用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) {
//創(chuàng)建兩個線程,分別調(diào)用mm()方法
//先創(chuàng)建Test01對象,通過對象名調(diào)用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();
//第三個線程調(diào)用靜態(tài)方法
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);
}
}
}
}