GGApe
GGApe
采纳率0%
2021-02-25 09:57

为什么代码没问题,却一直执行第一个线程?

package ccc;

import java.util.concurrent.locks.ReentrantLock;

public class LockTest {
    public static void main(String[] args) {
        Window w1 = new Window();

        Thread a = new Thread(w1);
        Thread b = new Thread(w1);
        Thread c = new Thread(w1);

        a.setName("窗口");
        b.setName("移动");
        c.setName("黄牛");

        a.start();
        b.start();
        c.start();
    }

}

class Window implements Runnable{
    private int ticket = 100;
    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while(true) {
            try {
                lock.lock();

                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + ":" + ticket);
                    ticket--;
                } else {
                    break;
                }
            }finally {
                lock.unlock();
            }
        }
    }
}






"D:\Program Files\Java\jdk1.8.0_231\bin\java.exe" "-javaagent:D:\JAVA学习\idea\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=60585:D:\JAVA学习\idea\IntelliJ IDEA 2019.3.3\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_231\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_231\jre\lib\rt.jar;D:\JAVA学习\SGG\2020最新学习路线图\out\production\diedline" day2.LockTest
窗口:100
窗口:99
窗口:98
窗口:97
窗口:96
窗口:95
窗口:94
窗口:93
窗口:92
窗口:91
窗口:90
窗口:89
窗口:88
窗口:87
窗口:86
窗口:85
窗口:84
窗口:83
窗口:82
窗口:81
窗口:80
窗口:79
窗口:78
窗口:77
窗口:76
窗口:75
窗口:74
窗口:73
窗口:72
窗口:71
窗口:70
窗口:69
窗口:68
窗口:67
窗口:66
窗口:65
窗口:64
窗口:63
窗口:62
窗口:61
窗口:60
窗口:59
窗口:58
窗口:57
窗口:56
窗口:55
窗口:54
窗口:53
窗口:52
窗口:51
窗口:50
窗口:49
窗口:48
窗口:47
窗口:46
窗口:45
窗口:44
窗口:43
窗口:42
窗口:41
窗口:40
窗口:39
窗口:38
窗口:37
窗口:36
窗口:35
窗口:34
窗口:33
窗口:32
窗口:31
窗口:30
窗口:29
窗口:28
窗口:27
窗口:26
窗口:25
窗口:24
窗口:23
窗口:22
窗口:21
窗口:20
窗口:19
窗口:18
窗口:17
窗口:16
窗口:15
窗口:14
窗口:13
窗口:12
窗口:11
窗口:10
窗口:9
窗口:8
窗口:7
窗口:6
窗口:5
窗口:4
窗口:3
窗口:2
窗口:1









  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

7条回答

  • ZhangShuiShou ZhangShuiShou 2月前

    sleep不会释放锁,你在36行那块的sleep加不加没什么影响,你加了sleep,只是暂停了当前的执行的线程,当前线程还是占领cpu资源的,结束后依旧执行的是刚刚暂停的进程,想要模拟网络延迟可以像其他人说的一样,加sleep放在锁的外面

    点赞 评论 复制链接分享
  • weixin_37519752 键盘行者 2月前
    class LockTest {
    
    	public static void main(String[] args) {
    		Window w1 = new Window();
    		Thread a = new Thread(w1);
    		Thread b = new Thread(w1);
    		Thread c = new Thread(w1);
    		a.setName("窗口");
    		b.setName("移动");
    		c.setName("黄牛");
    		a.start();
    		b.start();
    		c.start();
    	}
    
    }
    
    class Window implements Runnable {
    	private int ticket = 100;
    	private ReentrantLock lock = new ReentrantLock();
    
    	@Override
    	public void run() {
    		while (true) {
    			try {
    				lock.lock();
    				if (ticket > 0) {
    					System.out.println(Thread.currentThread().getName() + ":" + ticket);
    					ticket--;					
    				} else {
    					break;
    				}
    			} finally {
    				lock.unlock();
    				try {
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    
    		}
    
    	}
    
    }
    
    点赞 评论 复制链接分享
  • qq_36911145 封印di恶魔 2月前

    你用的这个采用的是非公平锁机制,第一次拿到的,第二次拿到的概率会比较大,所以就一直执行第一个,你把睡眠放到unlock下面,就可以看到抢锁的过程了

    点赞 评论 复制链接分享
  • yue_hu yue_hu 2月前

    用你代码跑了一下,结果却是符合预期的:

    窗口:100
    移动:99
    黄牛:98
    窗口:97
    移动:96
    移动:95
    黄牛:94
    窗口:93
    窗口:92
    移动:91
    黄牛:90
    窗口:89
    移动:88
    移动:87
    黄牛:86
    窗口:85
    移动:84
    黄牛:83
    黄牛:82
    窗口:81
    移动:80
    黄牛:79
    窗口:78
    移动:77
    黄牛:76
    黄牛:75
    窗口:74
    移动:73
    黄牛:72
    窗口:71
    移动:70
    移动:69
    移动:68
    黄牛:67
    黄牛:66
    窗口:65
    窗口:64
    移动:63
    黄牛:62
    窗口:61
    移动:60
    移动:59
    移动:58
    移动:57
    黄牛:56
    黄牛:55
    黄牛:54
    黄牛:53
    黄牛:52
    窗口:51
    窗口:50
    窗口:49
    窗口:48
    窗口:47
    移动:46
    黄牛:45
    窗口:44
    移动:43
    黄牛:42
    窗口:41
    窗口:40
    窗口:39
    移动:38
    黄牛:37
    窗口:36
    窗口:35
    窗口:34
    窗口:33
    窗口:32
    移动:31
    移动:30
    移动:29
    移动:28
    移动:27
    移动:26
    移动:25
    移动:24
    移动:23
    黄牛:22
    黄牛:21
    窗口:20
    窗口:19
    窗口:18
    窗口:17
    窗口:16
    窗口:15
    移动:14
    黄牛:13
    窗口:12
    移动:11
    移动:10
    黄牛:9
    黄牛:8
    窗口:7
    移动:6
    移动:5
    移动:4
    黄牛:3
    窗口:2
    移动:1
    点赞 评论 复制链接分享
  • huangzhigao886 被风吹过的回忆 2月前

    跟sleep的原因并不大,ReentrantLock内部初始化的时候默认是非公平锁,导致任意一个线程都有机会获得CPU的使用权,可能线程A更具有竞争力,可以改成加个reentrantLock改成公平锁试试

    点赞 评论 复制链接分享
  • huanhuilong 幻灰龙 2月前

    sleep 的时候lock还在持有锁,其他线程获取不到锁,你可以sleep之前unlock下,sleep之后再次lock下。另外,你的lock锁的资源是什么?一般lock只应发生在对资源读写的地方做保护,而不应该锁整个方法(行为),这个粒度太大了,性能不好也有问题

    点赞 评论 复制链接分享
  • liyunyou li叶叶 2月前

    可能是sleep的时间太短了

    点赞 评论 复制链接分享

为你推荐