Java:多线程死锁

    死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。

    产生死锁的原因:

    1.因为系统资源不足。

    2.进程运行推进的顺序不合适。    

    3.资源分配不当。

    产生死锁的条件:

  1. 互斥条件:所谓互斥就是进程在某一时间内独占资源。

  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

  3. 不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。

  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

    简单的来说:死锁就是因为多线程在访问对象的时候,A线程占用了对象object1,又想去占用对象object2,但是此时的object2对象已经被B线程占用,并且B线程又想去占用object2。两个线程同时占用对方想要的对象,但是又不释放自己占有的对象,两个线程互相等待,造成拥塞无法执行下去。

    

public class LockDemo implements Runnable
{
    private static Object object1 = new Object();
    
    private static Object object2 = new Object();
    
    private int flag = 0;
    
    public static void main(String[] args)
    {
        LockDemo run0 = new LockDemo();
        LockDemo run1 = new LockDemo();
        run0.flag = 1;
        run1.flag = 2;
        Thread thread1 = new Thread(run0);
        Thread thread2 = new Thread(run1);
        thread1.start();
        thread2.start();
    }
    
    @Override
    public void run()
    {
        System.out.println(flag);
        if (flag == 1)
        {
            synchronized (object1)
            {
                System.out.println("线程 : " + flag + "锁定obj1,休息0.5秒后锁定obj2去!");
                try
                {
                    Thread.sleep(500);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                synchronized (object2)
                {
                    System.out.println("线程 : " + flag + "访问 object2");
                }
            }
        }
        if (flag == 2)
        {
            synchronized (object2)
            {
                System.out.println("线程 : " + flag + "锁定obj2,休息0.5秒后锁定obj1去!");
                try
                {
                    Thread.sleep(500);
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                synchronized (object1)
                {
                    System.out.println("线程 : " + flag + "访问object1");
                }
            }
        }
        
    }
    
}

执行结果

1
2
线程 : 2锁定obj2,休息0.5秒后锁定obj1去!
线程 : 1锁定obj1,休息0.5秒后锁定obj2去!

    从执行的结果我们发现,每个线程都没有执行

System.out.println("线程 : " + flag + "访问object");

    因为线程1执行代码时把object1的时候加锁,然后去访问object2,但是此时的object2已经被线程2加上了锁,线程1和线程2分别占用object1和object2,又想去访问对方的占用的对象,显然是不可行的。就好比两个小孩交换玩具,一个小孩说:你先把玩具给我,我再把玩具给你,另外一个小孩说:不行,你要先把你的玩具给我,我再给你。结果两个小孩谁也不愿给谁,自然而然地在那僵持着。

    在代码中在修饰object对象的时候,使用了static关键字,如果不使用static 关键字的执行结果是什么样的呢?

1
线程 : 1锁定obj1,休息0.5秒后锁定obj2去!
2
线程 : 2锁定obj2,休息0.5秒后锁定obj1去!
线程 : 2访问object1
线程 : 1访问 object2

    可以看到并没有发生死锁,为什么?是因为使用static 关键字的时,两个object是公共的,不使用关键字时,两个object是线程自己用了两个独立的对象。同样我们打个比方,使用static关键修饰的object对象,就好比幼儿园中共有的两个玩具,大家谁都可以玩,但是每个小孩,都只能同时拥有一个。一个小朋友要是想要玩另外一个小朋友的玩具,必须要俩人互相交换。不用static关键字修饰的object对象,就好比每个小朋友自己带玩具来玩,不是共有的,我想玩哪个就玩哪个。

转载于:https://my.oschina.net/alexwan/blog/373058

### 关于ArcGIS License Server无法启动的解决方案 当遇到ArcGIS License Server无法启动的情况,可以从以下几个方面排查并解决问题: #### 1. **检查网络配置** 确保License Server所在的计算机能够被其他客户端正常访问。如果是在局域网环境中部署了ArcGIS Server Local,则需要确认该环境下的网络设置是否允许远程连接AO组件[^1]。 #### 2. **验证服务状态** 检查ArcGIS Server Object Manager (SOM) 的运行情况。通常情况下,在Host SOM机器上需将此服务更改为由本地系统账户登录,并重启相关服务来恢复其正常工作流程[^2]。 #### 3. **审查日志文件** 查看ArcGIS License Manager的日志记录,寻找任何可能指示错误原因的信息。这些日志可以帮助识别具体是什么阻止了许可服务器的成功初始化。 #### 4. **权限问题** 确认用于启动ArcGIS License Server的服务账号具有足够的权限执行所需操作。这包括但不限于读取/写入特定目录的权利以及与其他必要进程通信的能力。 #### 5. **软件版本兼容性** 保证所使用的ArcGIS产品及其依赖项之间存在良好的版本匹配度。不一致可能会导致意外行为完全失败激活license server的功能。 #### 示例代码片段:修改服务登录身份 以下是更改Windows服务登录凭据的一个简单PowerShell脚本例子: ```powershell $serviceName = "ArcGISServerObjectManager" $newUsername = ".\LocalSystemUser" # 替换为实际用户名 $newPassword = ConvertTo-SecureString "" -AsPlainText -Force Set-Service -Name $serviceName -StartupType Automatic New-ServiceCredential -ServiceName $serviceName -Account $newUsername -Password $newPassword Restart-Service -Name $serviceName ``` 上述脚本仅作为示范用途,请依据实际情况调整参数值后再实施。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值