线程同步
1.同步代码块
1)同步监听对象
1.{必须保证多个线程访问的是同一个同步监听对象
2.同步监听对象,可以是任意的对象【必须保证1】
3.this也是可以作为同步监听对象的【必须保证1】
4.一般最常用的:当前类的字节码对象,作为同步监听对象
TicketThread.class:一个类对应的字节码对象只有一个
2)继承
监听对象: 每new一个就是一个对象 所以不能用this
可以用: 1.当前类的字节码对象 TicketThread.class
2.任意对象:确保同一个 static Thread obj = new Thread();
3)实现
监听对象: 实现是一管三
可以用: 1.当前类的字节码对象TicketRunnable.class 可以
2.任意对象 实现字段不加static 行
3.this 可以
2.同步方法
1)继承
监听对象: 每new一个就是一个对象 所以不能用this
可以用:1.同步方法也是存在同步监听对象的:意味着线程还是必须保证访问的是同一个对象
1.一个方法static修饰:默认同步监听对象是TicketThread.class当前类的字节码对象
2.没有static修饰:this
2.注意:不能为了同步而加static,根据实际的业务做分析
2)实现
1.同步方法也是存在同步监听对象的:意味着线程还是必须保证访问的是同一个对象
1.一个方法static修饰:默认同步监听对象是TicketThread.class当前类的字节码对象
2.没有static修饰:this
3.锁机制
1)继承
2)实现
4.案例演示
package testMoney;
//银行类
public class Bank {
double salary; // 账户余额
boolean empty = true;// true 没钱
// 存钱
void save() {
synchronized (Bank.class) {
// 先判断是否有钱
if (!empty) {
// 有钱 线程等待
try {
Bank.class.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 没钱 就执行存钱操作
System.out.println("存钱之前:" + salary);
salary += 1000;
System.out.println("存钱之后:" + salary);
// 存完钱就改变余额状态
empty = false;
// 唤醒线程
Bank.class.notify();
}
}
// 取钱
void get() {
synchronized (Bank.class) {
// 先判断是否有钱
if (empty) {
// 没有钱 线程等待
try {
Bank.class.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 有钱 就执行取钱操作
System.out.println("取钱之前:" + salary);
salary -= 1000;
System.out.println("取钱之后:" + salary);
// 取完钱就改变余额状态
empty = true;
// 唤醒线程
Bank.class.notify();
}
}
}
package testMoney;
//取钱类
public class GetMoneyThread extends Thread {
Bank bank;
public GetMoneyThread(Bank bank) {
this.bank = bank;
}
@Override
public void run() {
// 取钱十二次
for (int i = 0; i < 12; i++) {
bank.get();
}
}
}
package testMoney;
//存钱类
public class SaveMoneyThread extends Thread {
Bank bank;
public SaveMoneyThread(Bank bank) {
this.bank = bank;
}
@Override
public void run() {
// 存钱十二次
for (int i = 0; i < 12; i++) {
bank.save();
}
}
}
package testMoney;
//测试类
public class Test {
public static void main(String[] args) {
Bank bank = new Bank();
SaveMoneyThread saveMoneyThread = new SaveMoneyThread(bank);
GetMoneyThread getMoneyThread = new GetMoneyThread(bank);
saveMoneyThread.start();
getMoneyThread.start();
}
}