java線程對(duì)象鎖
/**
* 線程對(duì)象鎖
*/
public class TestThread1{
? ?//使用字符串作為對(duì)象鎖,字符串為常量,唯一,所以任何遇到同一字符串對(duì)象鎖的線程都會(huì)轉(zhuǎn)為串行
? ?String person;
? ?public TestThread1(String name) {
? ? ? ?this.person = name;
? ?}
? ?public void useATM() {
? ? ? ?synchronized("排隊(duì)使用ATM機(jī)"){
? ? ? ? ? ?//ATM機(jī)只有一臺(tái),所有person使用都需要排隊(duì),鎖對(duì)象不是this而是ATM機(jī)
? ? ? ? ? ?System.out.println(person +" 操作ATM機(jī),插入銀行卡");
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?Thread.sleep(200);
? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ? ? ?}
? ? ? ? ? ?System.out.println(person +" 輸入密碼");
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?Thread.sleep(200);
? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ? ? ?}
? ? ? ? ? ?System.out.println(person +" 取款");
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?Thread.sleep(200);
? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ? ? ?}
? ? ? ? ? ?System.out.println(person +" 退卡離開");
? ? ? ?}
? ?}
}
class TakeMoneyThread extends Thread{
? ?TestThread1 t;
? ?public TakeMoneyThread(TestThread1 t){
? ? ? ?this.t = t;
? ?}
? ?@Override
? ?public void run() {
? ? ? ?t.useATM();
? ?}
? ?public static void main(String[] args) {
? ? ? ?new TakeMoneyThread(new TestThread1("張三")).start();
? ? ? ?new TakeMoneyThread(new TestThread1("李四")).start();
? ? ? ?new TakeMoneyThread(new TestThread1("王五")).start();
? ? ? ?//作為對(duì)象鎖的字符串可以是任何字符串,只要是相同字符串的對(duì)象鎖,執(zhí)行同步代碼的線程都會(huì)線程互斥
? ?}
}
class Visitor {
? ?//使用類對(duì)象作為對(duì)象鎖
? ?String name;
? ?public Visitor(String name) {
? ? ? ?this.name = name;
? ?}
? ?public void enter(){
? ? ? ?synchronized (Visitor.class){
? ? ? ? ? ?//所有游客排隊(duì)入場(chǎng),對(duì)象鎖為Visitor的類對(duì)象時(shí)范圍是所有visitor對(duì)象
? ? ? ? ? ?//當(dāng)程序中首次new Visitor()時(shí),JVM通過classLoader類加載器將Visitor類文件載入內(nèi)存,生成一個(gè)Class對(duì)象,Class類的對(duì)象緩存Visitor類的內(nèi)容,通過這個(gè)類對(duì)象來執(zhí)行new Visitor()的初始化
? ? ? ? ? ?System.out.println(name+"檢票");
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?Thread.sleep(200);
? ? ? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ? ? ?}
? ? ? ? ? ?System.out.println(name+"入場(chǎng)");
? ? ? ?}
? ?}
? ?public synchronized static void exit(String name){
? ? ? ?//游客排隊(duì)退場(chǎng),synchronized修飾靜態(tài)方法時(shí)對(duì)象鎖為類對(duì)象,因?yàn)殪o態(tài)方法屬于類
? ? ? ?System.out.println(name+"退場(chǎng)中");
? ? ? ?try {
? ? ? ? ? ?Thread.sleep(200);
? ? ? ?} catch (InterruptedException e) {
? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ?}
? ? ? ?System.out.println(name+"離開");
? ? ? ?//靜態(tài)方法內(nèi)部使用synchronized(Visitor.class){}括住所有內(nèi)容的效果和方法聲明上用synchronized修飾相同
? ?}
}
class Run1 implements Runnable{
? ?public Visitor v;
? ?public Run1(Visitor v) {
? ? ? ?this.v = v;
? ?}
? ?@Override
? ?public void run() {
? ? ? ?v.enter();
? ? ? ?//入場(chǎng),方法內(nèi)互斥
? ? ? ?System.out.println(v.name+"游覽中");
? ? ? ?//沒有設(shè)置互斥
? ? ? ?Visitor.exit(v.name);
? ? ? ?//出場(chǎng),方法內(nèi)互斥
? ?}
? ?public static void main(String[] args) {
? ? ? ?new Thread(new Run1(new Visitor("張三"))).start();
? ? ? ?new Thread(new Run1(new Visitor("李四"))).start();
? ?}
}