14.11.3 单一线程规则
基本原则:除了时间分配线程,不要再任何线程中接触Swing组件
特殊规则:
线程中可以添加、移除事件监听,然后触发时间分配线程
少量的Swing方法是安全的,如下:
记不住的话,还有个基本的,重绘方法是线程安全的,其他的当做不安全使用事件监听触发就可以了,不行就查查源码确定一下
补充1:示例:交替打印
以下给出三种解法(都是自己写):
解法一:使用锁+Condition
💐 加解锁
💐 如果不满足,阻塞 wait()
💐 满足处理后,signalAll()
class FooBar {
private int n;
private ReentrantLock lock;
private Condition c;
private volatile boolean used;
public FooBar(int n) {
this.n = n;
lock = new ReentrantLock();
c = lock.newCondition();
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
if(used) c.await();
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
used = true;
c.signalAll();
lock.unlock();
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
if(!used) c.await();
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
used = false;
c.signalAll();
lock.unlock();
}
}
}
解法二:使用synchronized+wait+notify
💐 Synchronized 方法或代码块
💐 不满足条件wait阻塞
💐 满足处理后notifyAll
class FooBar {
private int n;
private volatile boolean isFoo = true;
public FooBar(int n) {
this.n = n;
}
public synchronized void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
if(!isFoo)
this.wait();
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
isFoo = false;
this.notifyAll();
}
}
public synchronized void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
if(isFoo)
this.wait();
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
isFoo = true;
this.notifyAll();
}
}
}
解法三:使用 Semaphore
💐 几种信号建立不同的信号量(通常开始元素确定,一个有通行证,其他没有;不确定则大家都分配通行证)
💐 第一种信号处理完,给第二种信号量
💐 第二种信号处理完,给第一种信号量
class FooBar {
private int n;
private Semaphore semaphore1 = new Semaphore(1);
private Semaphore semaphore2 = new Semaphore(0);
public FooBar(int n) {
this.n = n;
}
public void foo(Runnable printFoo) throws InterruptedException {
for (int i = 0; i < n; i++) {
semaphore1.acquire();
// printFoo.run() outputs "foo". Do not change or remove this line.
printFoo.run();
semaphore2.release();
}
}
public void bar(Runnable printBar) throws InterruptedException {
for (int i = 0; i < n; i++) {
semaphore2.acquire();
// printBar.run() outputs "bar". Do not change or remove this line.
printBar.run();
semaphore1.release();
}
}
}
本来还想给第二个例子,写了几题都差不多,思路都是 Semaphore/lock+Condition/synchronized+wait+notifyAll
从下一节开始写补充的知识点:
💐 线程的生命周期
💐 创建线程的三种方式
💐 线程中常用锁:互斥锁、条件锁、自旋锁、读写锁、乐观锁、悲观锁、公平锁、非公平锁
相关内容:选择 《Java核心技术 卷1》查找相关笔记
评论🌹点赞👍收藏✨关注👀,是送给作者最好的礼物,愿我们共同学习,一起进步