上锁,根据操作系统所说的原则,对共享变量上锁,对临界区上锁。谁访问临界资源?就给谁上锁

同步监视器,它上锁的对象。

1.用关键字给方法上锁

2.用synchronized代码块上锁

默认上锁对象:this,指向自身。就是调用这个方法的对象,给他上锁。

安全的买票(给方法上锁)

public class SynchronizeTest {
//线程不安全
public static void main(String[] args) {
BuyTicker buyTicker = new BuyTicker();
new Thread(buyTicker,"lhh").start();
new Thread(buyTicker,"jhj").start();
new Thread(buyTicker,"黄牛").start();
}
}
class BuyTicker implements Runnable{
private int ticketNum = 10;
boolean flag = true;
@Override
public void run() {
while(flag){//外部停止方式
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}//对买票上锁,锁的this,this是指当前的对象。
public synchronized void buy() throws InterruptedException {//直接给方法上锁
//判断是否有票
if(ticketNum<=0){
System.out.println(Thread.currentThread().getName()+"票卖完了");
flag = false;
return;
}
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNum--);
}
}

安全的银行(给临界区上锁,)

如果给一个类的方法上锁了,实际上是给this也就是调用方法的这个对象上锁,比如你要是给run()上锁,就相当于你去取钱把银行锁了。但是取钱的人都还在银行里面。所以是要对账户上锁,因为我们逍遥操控的变量就是账户。

public class UnsafeBake {
public static void main(String[] args) {
Account account = new Account("结婚基金",1000);
Draw you = new Draw(account,50,"你");
Draw girlFriend = new Draw(account,100,"女朋友");
you.start();
girlFriend.start();
}
}
class Account{
String name;
int money;
public Account(String name, int money) {
this.name = name;
this.money = money;
}
}
class Draw extends Thread{
Account account;
int drawMoney;
int noMoney;
public Draw(Account account, int drawMoney, String name) {
super(name);
this.account = account;
this.drawMoney = drawMoney;
}
@Override
public void run() {
synchronized (account){
if(account.money-drawMoney<0){
System.out.println("余额不足");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money = account.money - drawMoney;
noMoney = noMoney +drawMoney;
System.out.println(account.name+"余额为:"+account.money);
System.out.println(this.getName()+"手里的钱"+noMoney);//继承THread可以直接写this
}
}
}

安全的列表

public class UnsafeList {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 100; i++) {
new Thread(()->{//lambda表达式
synchronized (list){//上锁临界资源list,下面是临界区操作临界资源的代码
list.add(Thread.currentThread().getName());
}
}).start();
}
try {
Thread.sleep(1000);//如果不让他睡,程序结束的时候线程也结束了一半了,列表元素就不够100
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}

最新文章

  1. code complete part2
  2. js使用Switch达到切换不同颜色的效果
  3. bootstrap panel 和table的使用
  4. iOS修改手机定位(非越狱任意位置)
  5. [hive小技巧]同一份数据多种处理
  6. Unity 区分不同平台
  7. hdu4639 hehe ——斐波纳契数列,找规律
  8. 数据的增量更新之EXISTS
  9. delphi xe3的helper语法 good
  10. UIImageView~动画播放的内存优化
  11. wpf 控件截屏
  12. UWP xaml 圆形头像
  13. php 下载文件的头信息 Determine Content Type
  14. Xcode intellisense meaning of letters in colored boxes like f,T,C,M,P,C,K,# etc
  15. 什么是IPFS?(三)
  16. 关于在Python2中使用列表推导式会遇到的问题
  17. 解决安装YouCompleteMe与Vim版本不兼容问题
  18. nginx ----&gt; nginx配置/反向代理/负载均衡
  19. Ascending Rating(单调队列)
  20. JSTL 学习

热门文章

  1. ASP.NET Core应用的7种依赖注入方式
  2. Error 不再支持源选项 5。请使用 6 或更高版本。
  3. Python3之turtle的基本用法#Python学习01#
  4. Apache Shiro反序列化漏洞复现
  5. 李飞飞团队最新论文:基于anchor关键点的类别级物体6D位姿跟踪
  6. O3优化模板
  7. MP3音频文件的剪切合并方法
  8. 学霸双胞胎开源斯坦福CS 221人工智能备忘录,图文并茂看懂反射、状态、变量、逻辑...
  9. k8s 集群管理和微服务 适合做啥
  10. Spring Boot整合Thymeleaf视图层