多个线程访问同一个资源可能会导致结果的不确定性,因此有时需要控制只有一个线程访问共享资源,此为线程同步。
一个是可以使用synchronized同步,一个是可以使用Lock。synchronized是也是隐式的锁。
class Account {
private Integer total;
public Account(int total) {
this.total = total;
}
public synchronized void draw(int money) {
if (total >= money) {
this.total = this.total - money;
System.out.println(Thread.currentThread().getName() + "剩下" + this.total);
} else {
System.out.println(Thread.currentThread().getName() + "不够了");
}
}
public synchronized int getTotal() {
return total;
}
}
public class Demo_02_04_1_ThreadSync {
public static void main(String[] args) {
Account account = new Account(100);
Runnable runnable = new Runnable() {
@Override
public void run() {
while (account.getTotal() >= 10) {
account.draw(10);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread A = new Thread(runnable);
A.setName("A");
Thread B = new Thread(runnable);
B.setName("B");
A.start();
B.start();
}
}
假设AB两个人从同一个账户里取钱,直接在draw这个方法加synchronized关键字,防止两个人同时进入draw
sychronized加在普通方法上,锁为当前实例对象
加在静态方法上,锁为当前类的Class
public void draw(int money) {
synchronized (total) {
if (total >= money) {
this.total = this.total - money;
System.out.println(Thread.currentThread().getName() + "剩下" + this.total);
} else {
System.out.println(Thread.currentThread().getName() + "不够了");
}
}
}
synchronized同步块,锁为()里边的对象
Lock lock = new ReentrantLock();
public void draw(int money) {
lock.lock();
try {
if (total >= money) {
this.total = this.total - money;
System.out.println(Thread.currentThread().getName() + "剩下" + this.total);
} else {
System.out.println(Thread.currentThread().getName() + "不够了");
}
} finally {
lock.unlock();
}
}
使用比较简单,进方法加锁,执行完释放,后面会专门介绍锁。