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
sleep 的时候lock还在持有锁,其他线程获取不到锁,你可以sleep之前unlock下,sleep之后再次lock下。另外,你的lock锁的资源是什么?一般lock只应发生在对资源读写的地方做保护,而不应该锁整个方法(行为),这个粒度太大了,性能不好也有问题。
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();
}
}
}
}
}
sleep不会释放锁,你在36行那块的sleep加不加没什么影响,你加了sleep,只是暂停了当前的执行的线程,当前线程还是占领cpu资源的,结束后依旧执行的是刚刚暂停的进程,想要模拟网络延迟可以像其他人说的一样,加sleep放在锁的外面
可能是sleep的时间太短了
跟sleep的原因并不大,ReentrantLock内部初始化的时候默认是非公平锁,导致任意一个线程都有机会获得CPU的使用权,可能线程A更具有竞争力,可以改成加个reentrantLock改成公平锁试试
用你代码跑了一下,结果却是符合预期的:
窗口: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
你用的这个采用的是非公平锁机制,第一次拿到的,第二次拿到的概率会比较大,所以就一直执行第一个,你把睡眠放到unlock下面,就可以看到抢锁的过程了