java线程对象锁
/**
* 线程对象锁
*/
public class TestThread1{
//使用字符串作为对象锁,字符串为常量,唯一,所以任何遇到同一字符串对象锁的线程都会转为串行
String person;
public TestThread1(String name) {
this.person = name;
}
public void useATM() {
synchronized("排队使用ATM机"){
//ATM机只有一台,所有person使用都需要排队,锁对象不是this而是ATM机
System.out.println(person +" 操作ATM机,插入银行卡");
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();
//作为对象锁的字符串可以是任何字符串,只要是相同字符串的对象锁,执行同步代码的线程都会线程互斥
}
}
class Visitor {
//使用类对象作为对象锁
String name;
public Visitor(String name) {
this.name = name;
}
public void enter(){
synchronized (Visitor.class){
//所有游客排队入场,对象锁为Visitor的类对象时范围是所有visitor对象
//当程序中首次new Visitor()时,JVM通过classLoader类加载器将Visitor类文件载入内存,生成一个Class对象,Class类的对象缓存Visitor类的内容,通过这个类对象来执行new Visitor()的初始化
System.out.println(name+"检票");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(name+"入场");
}
}
public synchronized static void exit(String name){
//游客排队退场,synchronized修饰静态方法时对象锁为类对象,因为静态方法属于类
System.out.println(name+"退场中");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(name+"离开");
//静态方法内部使用synchronized(Visitor.class){}括住所有内容的效果和方法声明上用synchronized修饰相同
}
}
class Run1 implements Runnable{
public Visitor v;
public Run1(Visitor v) {
this.v = v;
}
@Override
public void run() {
v.enter();
//入场,方法内互斥
System.out.println(v.name+"游览中");
//没有设置互斥
Visitor.exit(v.name);
//出场,方法内互斥
}
public static void main(String[] args) {
new Thread(new Run1(new Visitor("张三"))).start();
new Thread(new Run1(new Visitor("李四"))).start();
}
}