0
点赞
收藏
分享

微信扫一扫

第14章 多线程(16)Swing 的线程补充+线程示例与常见解法

灯火南山 2022-05-05 阅读 101
javaidea

 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》查找相关笔记

评论🌹点赞👍收藏✨关注👀,是送给作者最好的礼物,愿我们共同学习,一起进步

举报

相关推荐

0 条评论