synchronized 设置为同步方法
package synchronizedTest;
//模拟买票
public class UnsafeBuyTicket {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket,"用户A").start();
new Thread(buyTicket,"用户B").start();
new Thread(buyTicket,"用户C").start();
}
}
//不安全
class BuyTicket implements Runnable{
// 设置票数
private static int ticketNums = 10;
@Override
public void run() {
while (true){
if(ticketNums<0){
break;
}
try {
System.out.println(Thread.currentThread().getName()+"买到了票,剩余" + --ticketNums + "张票");
Thread.sleep(100);//防止票被一个人买完,模拟延迟
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
发现线程并不安全
这时需要用到synchronized 设置为同步方法
class BuyTicket implements Runnable{
// 设置票数
private static int ticketNums = 10;
@Override
public synchronized void run() {//只需要在这里加synchronized 据可以解决问题
while (true){
if(ticketNums<=0){
break;
}
try {
System.out.println(Thread.currentThread().getName()+"买到了票,剩余" + --ticketNums + "张票");
Thread.sleep(100);//防止票被一个人买完,模拟延迟
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
synchronized 设置为同步对象
package synchronizedTest;
//模拟银行取钱
public class Bank {
public static void main(String[] args) {
//账户
Account account = new Account(100, "银行卡");
Drawing a = new Drawing(account, 50, "A");
Drawing b = new Drawing(account, 100, "B");
a.start();
b.start();
}
}
//账户
class Account{
int money;
String name;
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
//模拟银行取款
class Drawing extends Thread{
//账户
Account account;
//取款金额
int drawingMoney;
public Drawing(Account account,int drawingMoney,String name){
super(name);
this.account = account;
this.drawingMoney = drawingMoney;
}
@Override
public void run() {
//判断账户余额是否够取
if(account.money - drawingMoney < 0){
System.out.println(Thread.currentThread().getName()+"取钱失败,账户钱不够");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money -= drawingMoney;
// this.getName() == Thread.currentThread().getName()
System.out.println(this.getName()+"取了"+drawingMoney);
System.out.println("账户余额:" + account.money);
}
}
synchronized 锁的是this即Drawing,
当A进程进来时发现A对象Drawing没锁,则加锁运行run方法
当B进程进来时发现B对象Drawing没锁,则加锁运行run方法
(注意A和B的对象不同,所以不能锁run方法,应该锁共享资源即Account)
package synchronizedTest;
//模拟银行取钱
public class Bank {
public static void main(String[] args) {
//账户
Account account = new Account(100, "银行卡");
Drawing a = new Drawing(account, 50, "A");
Drawing b = new Drawing(account, 100, "B");
a.start();
b.start();
}
}
//账户
class Account{
int money;
String name;
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
//模拟银行取款
class Drawing extends Thread{
//账户
Account account;
//取款金额
int drawingMoney;
public Drawing(Account account,int drawingMoney,String name){
super(name);
this.account = account;
this.drawingMoney = drawingMoney;
}
@Override
public void run() {
synchronized (account){
//判断账户余额是否够取
if(account.money - drawingMoney < 0){
System.out.println(Thread.currentThread().getName()+"取钱失败,账户钱不够");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money -= drawingMoney;
// this.getName() == Thread.currentThread().getName()
System.out.println(this.getName()+"取了"+drawingMoney);
System.out.println("账户余额:" + account.money);
}
}
}