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

wordpress mkv格式优化推广服务

wordpress mkv格式,优化推广服务,手机版免费个人简历,c语言 网站开发死锁 在Java中使用多线程,就会有可能导致死锁问题。死锁会让程序一直卡住,程序不再往下执行。 我们只能通过中止并重启的方式来让程序重新执行。 这是我们非常不愿意看到的一种现象,我们要尽可能避免死锁的情况发生! 死锁的原因…

死锁

在Java中使用多线程,就会有可能导致死锁问题。死锁会让程序一直住,程序不再往下执行。

我们只能通过中止并重启的方式来让程序重新执行。
这是我们非常不愿意看到的一种现象,我们要尽可能避免死锁的情况发生!

死锁的原因:

  1. 当前线程拥有其他线程需要的资源
  2. 当前线程等待其他线程已拥有的资源
  3. 都不放弃自己拥有的资源
锁顺序死锁

线程1调用leftRight()方法,得到left锁
同时线程2调用rightLeft()方法,得到right锁线程1和线程2都继续执行,此时线程1需要right锁才能继续往下执行。此时线程2需要left锁才能继续往下执行。
线程1的left锁并没有释放,线程2的right锁也没有释放。
所以他们都只能等待,而这种等待是无期限的–>永久等待–>死锁

class Demo implements Runnable{private final Object left = new Object(); private final Object right = new Object();@Overridepublic void run() {leftRight();rightLeft();}public void leftRight() {synchronized (left) {System.out.println("线程" + Thread.currentThread().getName() + "拿到left,还需要right");synchronized (right) {System.out.println("线程" + Thread.currentThread().getName() + "拿到left和right");}}}public void rightLeft() {synchronized (right) {System.out.println("线程" + Thread.currentThread().getName() + "拿到right,还需要left");synchronized (left) {System.out.println("线程" + Thread.currentThread().getName() + "拿到right和left");}}}
}
动态锁顺序死锁

代码释义:获取源账户与目标账户,判断余额充足后进行加减操作。
死锁现象:线程1源账户a,目标账户b。线程2源账户b,目标账户a。

public class ThreadTest {public static void main(String[] args) {Test test = new Test();new Thread(test, "1").start();new Thread(test, "2").start();new Thread(test, "3").start();new Thread(test, "4").start();}
}class Test implements Runnable {Account a = new Account("A", 1000);Account b = new Account("B", 1000);@Overridepublic void run() {transferMoney(a, b, 100);transferMoney(b, a, 100);}public void transferMoney(Account fromAccount, Account toAccount, double money) {synchronized (fromAccount) {System.out.println("线程" + Thread.currentThread().getName() + "获得账户" + fromAccount.getName());synchronized (toAccount) {System.out.println("线程" + Thread.currentThread().getName() + "获得账户" + toAccount.getName());if (fromAccount.getMoney() < money) {System.out.println("余额不足");} else {fromAccount.setMoney(fromAccount.getMoney() - money);toAccount.setMoney(toAccount.getMoney() + money);System.out.println("转账后:" + fromAccount.getName() + "的余额:" +fromAccount.getMoney());System.out.println("转账后:" + toAccount.getName() + "的余额:" + toAccount.getMoney());}}}}
}
@Data
class Account {public Account(String name, double money) {this.name = name;this.money = money;}private String name;private double money;
}
协作对象之间发生死锁

getImage()setLocation(Point location)都需要获取两个锁,且在操作途中是没有释放锁的。

这就是隐式获取两个锁(对象之间协作)很容易造成死锁

public class CooperatingDeadlock {class Taxi {private Point location, destination;private final Dispatcher dispatcher;public Taxi(Dispatcher dispatcher) {this.dispatcher = dispatcher;}public synchronized Point getLocation() {return location;}// setLocation 需要Taxi内置锁public synchronized void setLocation(Point location) {this.location = location;if (location.equals(destination))// 调用notifyAvailable()需要Dispatcher内置锁dispatcher.notifyAvailable(this);}public synchronized Point getDestination() {return destination;}public synchronized void setDestination(Point destination) {this.destination = destination;}}class Dispatcher {private final Set<Taxi> taxis;private final Set<Taxi> availableTaxis;public Dispatcher() {taxis = new HashSet<Taxi>();availableTaxis = new HashSet<Taxi>();}public synchronized void notifyAvailable(Taxi taxi) {availableTaxis.add(taxi);}// 调用getImage()需要Dispatcher内置锁public synchronized Image getImage() {Image image = new Image();for (Taxi t : availableTaxis)// 调用getLocation()需要Taxi内置锁image.drawMarker(t.getLocation());return image;}}class Image {public void drawMarker(Point p) {}}
}

避免死锁的方法

避免死锁可以概括成三种方法:

  • 固定加锁的顺序(针对锁顺序死锁)
  • 开放调用(针对对象之间协作造成的死锁)
  • 使用定时锁–>tryLock()如果等待获取锁时间超时,则抛出异常而不是一直等待
固定锁顺序避免死锁

得到对应的hash值来固定加锁的顺序,这样不会出现死锁。

public class OrderLock {private static final Object tieLock = new Object();public void transferMoney(final Account fromAccount, final Account toAccount, final DollarAmount amount)throws InsufficientFundsException {class Helper {public void transfer() throws InsufficientFundsException {if (fromAccount.getBalance().compareTo(amount) < 0)throw new InsufficientFundsException();else {fromAccount.debit(amount);toAccount.credit(amount);}}}int fromHash = System.identityHashCode(fromAccount);int toHash = System.identityHashCode(toAccount);if (fromHash < toHash) {synchronized (fromAccount) {synchronized (toAccount) {new Helper().transfer();}}} else if (fromHash > toHash) {synchronized (toAccount) {synchronized (fromAccount) {new Helper().transfer();}}} else {synchronized (tieLock) {synchronized (fromAccount) {synchronized (toAccount) {new Helper().transfer();}}}}}
}
开放调用避免死锁

在协作对象之间发生死锁的例子中,主要是因为在调用某个方法时就需要持有锁,并且在方法内部也调用了其他带锁的方法。

如果在调用某个方法时不需要持有锁,那么这种调用被称为开放调用。同步代码块最好仅被用于保护那些涉及共享状态的操作

class CooperatingLock {@ThreadSafeclass Taxi {@GuardedBy("this")private Point location, destination;private final Dispatcher dispatcher;public Taxi(Dispatcher dispatcher) {this.dispatcher = dispatcher;}public synchronized Point getLocation() {return location;}public void setLocation(Point location) {boolean reachedDestination;synchronized (this) {this.location = location;reachedDestination = location.equals(destination);}if (reachedDestination)dispatcher.notifyAvailable(this);}public synchronized Point getDestination() {return destination;}public synchronized void setDestination(Point destination) {this.destination = destination;}}@ThreadSafeclass Dispatcher {@GuardedBy("this")private final Set<Taxi> taxis;@GuardedBy("this")private final Set<Taxi> availableTaxis;public Dispatcher() {taxis = new HashSet<Taxi>();availableTaxis = new HashSet<Taxi>();}public synchronized void notifyAvailable(Taxi taxi) {availableTaxis.add(taxi);}public Image getImage() {Set<Taxi> copy;synchronized (this) {copy = new HashSet<Taxi>(availableTaxis);}Image image = new Image();for (Taxi t : copy)image.drawMarker(t.getLocation());return image;}}class Image {public void drawMarker(Point p) {}}
}
使用定时锁

使用显式Lock锁,在获取锁时使用tryLock()方法。当等待超时的时候,tryLock()不会一直等待,而是返回错误信息。

使用tryLock()能够有效避免死锁问题。tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。

public class tryLock {public static void main(String[] args) {System.out.println("开始");final Lock lock = new ReentrantLock();new Thread() {@Overridepublic void run() {String tName = Thread.currentThread().getName();if (lock.tryLock()) {System.out.println(tName + "获取到锁!");} else {System.out.println(tName + "获取不到锁!");return;}try {for (int i = 0; i < 5; i++) {System.out.println(tName + ":" + i);}Thread.sleep(5000);} catch (Exception e) {System.out.println(tName + "出错了!!!");} finally {System.out.println(tName + "释放锁!!");lock.unlock();}}}.start();new Thread() {@Overridepublic void run() {String tName = Thread.currentThread().getName();if (lock.tryLock()) {System.out.println(tName + "获取到锁!");} else {System.out.println(tName + "获取不到锁!");return;}try {for (int i = 0; i < 5; i++) {System.out.println(tName + ":" + i);}} catch (Exception e) {System.out.println(tName + "出错了!!!");} finally {System.out.println(tName + "释放锁!!");lock.unlock();}}}.start();System.out.println("结束");}
}

总结

发生死锁的原因主要由于:

  • 线程之间交错执行

    解决:以固定的顺序加锁

  • 执行某方法时就需要持有锁,且不释放

    解决:缩减同步代码块范围,最好仅操作共享变量时才加锁

  • 永久等待

    解决:使用tryLock()定时锁,超时则返回错误信息

http://www.hrbkazy.com/news/18189.html

相关文章:

  • 吉林移动网站广州seo推广营销
  • php做网站开发有什么框架百度文库网页版
  • wordpress写接口seo课程培训学校
  • 重庆整合营销网站建设泉州百度广告
  • 丹阳网站建设报价seo技术培训唐山
  • 黑龙江省建设网站首页登封网站设计
  • 国际新闻哪个app好seo优化方案模板
  • WordPress导入用户数据如何做seo整站优化
  • 网页设计国外设计欣赏网站百度官方网站首页
  • 用vb怎么做网站百度搜索热词查询
  • 长治做网站公司怎样才能上百度
  • 公司的网站难不难做国内好的seo网站
  • 常熟做网站的b2b商务平台
  • 做调查赚钱哪些网站最靠谱求个没封的网站2022
  • 北京网站建设最好公司网站查询ip地址查询
  • 牛 网站建设建一个企业网站多少钱
  • 帮人做兼职的网站厦门seo关键词优化代运营
  • jsp网站开发工资寻找客户的渠道和方法
  • 南京网站建设制作浏览器打开网站
  • wordpress生成微信小程序seo网络公司
  • 武汉便宜网站建设竞价推广托管公司介绍
  • 有哪些免费网站可以做店招站长之家ip查询
  • 如何做jquery音乐网站网站优化seo培
  • 网站做外链的具体步骤宁波品牌网站推广优化
  • 网站多语切换怎么做网络软文是什么意思
  • 移动建站价格产品推广介绍怎么写
  • 国内做音乐网站免费正能量erp软件下载
  • 怎么建立公司网站费用sem和seo的区别
  • 在线修图网站上海网络营销公司
  • 长沙网站设计制作色盲怎么治疗