当前位置: 首页 > news >正文

用html5做商城网站怎么做大一html网页制作作业简单

用html5做商城网站怎么做,大一html网页制作作业简单,沈阳做网站的公司排名,web制作网页怎么在鼠标经过是换界面死锁,一组互相竞争的资源的线程之间相互等待,导致永久阻塞的现象。 如下图所示: 与死锁对应的,还有活锁,是指线程没有出现阻塞,但是无限循环。 有一个经典的银行转账例子如下: 我们有个账户类…

死锁,一组互相竞争的资源的线程之间相互等待,导致永久阻塞的现象。

如下图所示:
在这里插入图片描述
与死锁对应的,还有活锁,是指线程没有出现阻塞,但是无限循环。


有一个经典的银行转账例子如下:

我们有个账户类,其中有两个属性:账户名和余额。
它有两个方法:转入、转出。

public class Account {private String countName;private int balance;public Account(String countName, int balance) {this.countName = countName;this.balance = balance;}/*** 转出金额,更新转出方余额,金额减少* @param amount*/public void debit(int amount){this.balance -= amount;}/*** 存入金额,更新转入方余额,金额增多* @param amount*/public void credit(int amount){this.balance += amount;}public String getCountName() {return countName;}public void setCountName(String countName) {this.countName = countName;}public int getBalance() {return balance;}public void setBalance(int balance) {this.balance = balance;}
}

还有一个转账操作类,它有三个属性:转入账户、转出账户、转账金额。
它实现了Runnable接口,run方法中是转账逻辑代码。
我们使用 while(true) 让他不停的进行转账操作:如果账户余额大于转账金额,就让转出账号减少amount,转入账户增加amount。打印出线程名、金额转移方向、以及每个账户余额。
我们在main方法中进行测试,创建两个转账账户,使用两个线程操作这两个账户,让他们相互转账。

public class TransferAccount implements Runnable{private Account fromAccount;private Account toAccount;private int amount;public TransferAccount(Account fromAccount, Account toAccount, int amount) {this.fromAccount = fromAccount;this.toAccount = toAccount;this.amount = amount;}@Overridepublic void run() {while(true){synchronized (fromAccount){synchronized (toAccount){if(fromAccount.getBalance()>=amount) {fromAccount.debit(amount);toAccount.credit(amount);}System.out.println(Thread.currentThread().getName());System.out.println(fromAccount.getCountName()+"->"+toAccount.getCountName()+":"+amount );System.out.println(fromAccount.getCountName() +"账户余额:"+ fromAccount.getBalance());System.out.println(toAccount.getCountName() +"账户余额:"+ toAccount.getBalance());}}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {Account bigHead = new Account("冤大头",100000);Account smallKill = new Account("门小抠",200000);new Thread(new TransferAccount(bigHead,smallKill,10)).start();new Thread(new TransferAccount(smallKill,bigHead,20)).start();}}

执行main方法后的输出结果:

Thread-0
冤大头->门小抠:10
冤大头账户余额:99990
门小抠账户余额:200010
Thread-1
门小抠->冤大头:20
门小抠账户余额:199990
冤大头账户余额:100010
Thread-1
门小抠->冤大头:20
门小抠账户余额:199970
冤大头账户余额:100030
Thread-0
冤大头->门小抠:10
冤大头账户余额:100020
门小抠账户余额:199980
Thread-0
冤大头->门小抠:10
冤大头账户余额:100010
门小抠账户余额:199990
Thread-1
门小抠->冤大头:20
门小抠账户余额:199970
冤大头账户余额:100030
Thread-0
冤大头->门小抠:10
冤大头账户余额:100020
门小抠账户余额:199980
Thread-1
门小抠->冤大头:20
门小抠账户余额:199960
冤大头账户余额:100040
Thread-0
冤大头->门小抠:10
冤大头账户余额:100030
门小抠账户余额:199970
Thread-1
门小抠->冤大头:20
门小抠账户余额:199950
冤大头账户余额:100050
Thread-0
冤大头->门小抠:10
冤大头账户余额:100040
门小抠账户余额:199960
Thread-1
门小抠->冤大头:20
门小抠账户余额:199940
冤大头账户余额:100060

这时,我们发现进程还在运行,但是控台停止输出了,它停在那里了。
截图如下:
在这里插入图片描述

这时我们使用 jps 来查看一下java进程:

D:\open_source\MyBatis\MyThread\target\classes\demo>jps
23600
24676 Launcher
40244 Jps
23672 TransferAccount

然后输入 使用jstack来看详情:

D:\open_source\MyBatis\MyThread\target\classes\demo>jstack 23672
2023-02-26 18:37:57
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.351-b10 mixed mode):"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x000001b4fc785800 nid=0x6530 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"Thread-1" #13 prio=5 os_prio=0 tid=0x000001b4fc77f800 nid=0x887c waiting for monitor entry [0x000000467adff000]java.lang.Thread.State: BLOCKED (on object monitor)at deadlock.TransferAccount.run(TransferAccount.java:20)- waiting to lock <0x000000076c5a4610> (a deadlock.Account)- locked <0x000000076c5a4658> (a deadlock.Account)at java.lang.Thread.run(Thread.java:750)"Thread-0" #12 prio=5 os_prio=0 tid=0x000001b4fc77c800 nid=0x8c80 waiting for monitor entry [0x000000467acff000]java.lang.Thread.State: BLOCKED (on object monitor)at deadlock.TransferAccount.run(TransferAccount.java:20)- waiting to lock <0x000000076c5a4658> (a deadlock.Account)- locked <0x000000076c5a4610> (a deadlock.Account)at java.lang.Thread.run(Thread.java:750)......Found one Java-level deadlock:
=============================
"Thread-1":waiting to lock monitor 0x000001b4fa208eb8 (object 0x000000076c5a4610, a deadlock.Account),which is held by "Thread-0"
"Thread-0":waiting to lock monitor 0x000001b4fa208e08 (object 0x000000076c5a4658, a deadlock.Account),which is held by "Thread-1"Java stack information for the threads listed above:
===================================================
"Thread-1":at deadlock.TransferAccount.run(TransferAccount.java:20)- waiting to lock <0x000000076c5a4610> (a deadlock.Account)- locked <0x000000076c5a4658> (a deadlock.Account)at java.lang.Thread.run(Thread.java:750)
"Thread-0":at deadlock.TransferAccount.run(TransferAccount.java:20)- waiting to lock <0x000000076c5a4658> (a deadlock.Account)- locked <0x000000076c5a4610> (a deadlock.Account)at java.lang.Thread.run(Thread.java:750)Found 1 deadlock.

我们可以看到,其中Thread-0和Thread-1都已经处于BLOCK状态,发生了死锁。


导致死锁发生,必须同时满足四个条件:互斥、占有且等待、不可抢占、循环等待。

  • 互斥:共享资源A和B只能被一个线程占用。
  • 占有且等待:线程Thread-1 已经取得共享资源X,在等待共享资源Y的时候,不释放共享资源X。
  • 不可抢占:其他线程不能强行抢占线程Thread-1 占有的资源。
  • 循环等待:线程Thread-1 等待线程Thread-2 占有的资源,线程Thread-2等待Thread-1 占有的资源。

如何解决?

如果要解决死锁问题,只需要破坏其中一个条件,使其不满足即可。
除了互斥(多线程的基础)之外,其他三个条件都可以考虑破坏。
实际中遇到死锁,只能重启,如果还是死锁,要定位问题点,然后修复代码(破坏掉死锁必须满足的条件之一)后重新发布。


我们来尝试破坏占有且等待的方式来破坏死锁:
新增加一个分配的类:Allocator,它有一个账户池。每个转账线程中要判断,账户池中是否已有此账户,如果没有可以转账,有的话就不转账。就可以避免共享资源同时存在于两个线程。

import java.util.ArrayList;
import java.util.List;public class Allocator {private List<Object> list = new ArrayList<>();synchronized boolean apply(Object fromAccount,Object toAccount){if(list.contains(fromAccount)||list.contains(toAccount)){return false;}list.add(fromAccount);list.add(toAccount);return true;}synchronized void free(Object fromAccount,Object toAccount){list.remove(fromAccount);list.remove(toAccount);}
}//相应的,TransAcount也要做修改:
public class TransferAccount implements Runnable {private Account fromAccount;private Account toAccount;private int amount;private Allocator allocator;public TransferAccount(Account fromAccount, Account toAccount, int amount, Allocator allocator) {this.fromAccount = fromAccount;this.toAccount = toAccount;this.amount = amount;this.allocator = allocator;}@Overridepublic void run() {while (true) {//判断账户是否已经分配过if (allocator.apply(fromAccount, toAccount)) {try {synchronized (fromAccount) {synchronized (toAccount) {if (fromAccount.getBalance() >= amount) {fromAccount.debit(amount);toAccount.credit(amount);}System.out.println(Thread.currentThread().getName());System.out.println(fromAccount.getCountName() + "->" + toAccount.getCountName() + ":" + amount);System.out.println(fromAccount.getCountName() + "账户余额:" + fromAccount.getBalance());System.out.println(toAccount.getCountName() + "账户余额:" + toAccount.getBalance());}}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}finally {allocator.free(fromAccount,toAccount);}}}}public static void main(String[] args) {Account bigHead = new Account("冤大头", 100000);Account smallKill = new Account("门小抠", 200000);Allocator allocator = new Allocator();new Thread(new TransferAccount(bigHead, smallKill, 10, allocator)).start();new Thread(new TransferAccount(smallKill, bigHead, 20, allocator)).start();}}

我们来避免第三个条件:使用Lock来替换掉 Synchronized。
Synchronized加锁后,要等到资源释放,而且锁是不可抢占的。
Lock中有个方法 tryLock,可以返回布尔值,如果返回fasle就不会进去。tryLock不会持续持有锁。

public class TransferAccount2 implements Runnable{private Account fromAccount;private Account toAccount;private int amount;private Lock fromAccountLock = new ReentrantLock();private Lock toAccountLock = new ReentrantLock();public TransferAccount2(Account fromAccount, Account toAccount, int amount) {this.fromAccount = fromAccount;this.toAccount = toAccount;this.amount = amount;}@Overridepublic void run() {while(true){//synchronized (fromAccount){if(fromAccountLock.tryLock()){if(toAccountLock.tryLock()){if(fromAccount.getBalance()>=amount) {fromAccount.debit(amount);toAccount.credit(amount);}System.out.println(Thread.currentThread().getName());System.out.println(fromAccount.getCountName()+"->"+toAccount.getCountName()+":"+amount );System.out.println(fromAccount.getCountName() +"账户余额:"+ fromAccount.getBalance());System.out.println(toAccount.getCountName() +"账户余额:"+ toAccount.getBalance());}}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {Account bigHead = new Account("冤大头",100000);Account smallKill = new Account("门小抠",200000);new Thread(new TransferAccount2(bigHead,smallKill,10)).start();new Thread(new TransferAccount2(smallKill,bigHead,20)).start();}}

http://www.hkea.cn/news/86816/

相关文章:

  • 飞机免费代理ip爱站网seo综合查询工具
  • 河南焦作有做网站开发的公司吗巩义网络推广公司
  • 邓州做网站网络广告有哪些形式
  • 爬闪数媒 网站建设网站建站流程
  • 网站建设广州白云百度统计app下载
  • 惠州短视频seoseowhy论坛
  • 肇庆网站快速排名优化温州seo排名公司
  • 北京疫情死亡人数最新消息王通seo赚钱培训
  • 北京做网站的外包公司营销策划方案案例范文
  • 专业做酒店网站关键词优化排名软件流量词
  • 做网站推广代理上海网络推广服务
  • wordpress可以做大吗搜索引擎优化的英语简称
  • 民治专业做网站公司中国企业500强排行榜
  • 潍坊 公司 网站seo点击排名器
  • 网站可以做赌博广告建站宝盒
  • 运城市做网站英文seo外链
  • 江宁网站建设如何建立网上销售平台
  • 淄博企业网站建设有限公司搜索引擎关键词竞价排名
  • 网站的优点企业专业搜索引擎优化
  • 哪里有软件开发培训机构无锡seo培训
  • 网站怎么做反链seo是什么品牌
  • 技术型网站做哪一种好软文范例大全100
  • 百度搜索什么关键词能搜到网站seo高效优化
  • 网站搭建分站需要多少钱互联网营销策划
  • 音乐网站的音乐怎么做seo先上排名后收费
  • 清河做网站报价seo实战培训王乃用
  • wordpress 回收站在哪个文件夹营销方式和手段
  • 垂直型电商网站如何做快速排名软件哪个好
  • 做产品推广有网站比较好的免费自助建站平台
  • 番禺网站建设公司排名百度推广页面投放