【多线程:综合练习】

简介: 【多线程:综合练习】

【多线程:综合练习】

01.介绍

我们提出两个问题 分别用wait/notify,park/unpark,await/signal解决。

02.问题一

介绍

我们创建两个线程 从1交替打印到10

wait/notify实现

@Slf4j(topic = "c.TestSun")
public class TestSun {
    public static void main(String[] args) {
        // 交替打印五轮
        TestNumber num = new TestNumber(5);
        new Thread(()->{
            num.print(true);
        },"t1").start();

        new Thread(()->{
            num.print(false);
        },"t2").start();
    }
}
@Slf4j(topic = "c.TestNumber")
class TestNumber{
    private int cnt = 1;
    private boolean flag = true;
    private final int count;
    public TestNumber(int count){
        this.count=count;
    }
    public void print(boolean flagN){
        synchronized (this){
            for (int i=0;i<count;i++){
                while (flag!=flagN){
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("{}",cnt);
                cnt++;
                flag=!flag;
                this.notify();
            }
        }
    }
}

结果

23:45:24.559 c.TestNumber [t1] - 1
23:45:24.562 c.TestNumber [t2] - 2
23:45:24.562 c.TestNumber [t1] - 3
23:45:24.562 c.TestNumber [t2] - 4
23:45:24.562 c.TestNumber [t1] - 5
23:45:24.562 c.TestNumber [t2] - 6
23:45:24.562 c.TestNumber [t1] - 7
23:45:24.562 c.TestNumber [t2] - 8
23:45:24.562 c.TestNumber [t1] - 9
23:45:24.562 c.TestNumber [t2] - 10

park/unpark实现

@Slf4j(topic = "c.TestSunPark")
public class TestSunPark {
    static Thread t1;
    static Thread t2;
    public static void main(String[] args) {
        // 交替打印5次
        TestParkNum num = new TestParkNum(5);
        t1 = new Thread(()->{
            num.print(t2);
        },"t1");
        t2 = new Thread(()->{
            num.print(t1);
        },"t2");
        t1.start();
        t2.start();
        LockSupport.unpark(t1);
    }
}
@Slf4j(topic = "c.TestParkNum")
class TestParkNum{
    private int cnt = 1;
    private final int count;
    public TestParkNum(int count){
        this.count=count;
    }
    public void print(Thread next){
        for (int i=0;i<count;i++){
            LockSupport.park();
            log.debug("{}",cnt);
            cnt++;
            LockSupport.unpark(next);
        }
    }
}

结果

23:49:38.354 c.TestSunReenNum [t1] - 1
23:49:38.357 c.TestSunReenNum [t2] - 2
23:49:38.357 c.TestSunReenNum [t1] - 3
23:49:38.357 c.TestSunReenNum [t2] - 4
23:49:38.358 c.TestSunReenNum [t1] - 5
23:49:38.358 c.TestSunReenNum [t2] - 6
23:49:38.358 c.TestSunReenNum [t1] - 7
23:49:38.358 c.TestSunReenNum [t2] - 8
23:49:38.358 c.TestSunReenNum [t1] - 9
23:49:38.358 c.TestSunReenNum [t2] - 10

await/signal实现

public class TestSunReen {
    public static void main(String[] args) {
        // 交替打印5次
        TestSunReenNum num = new TestSunReenNum(5);
        Condition condition = num.newCondition();
        new Thread(()->{
            num.print(true,condition);
        },"t1").start();

        new Thread(()->{
            num.print(false,condition);
        },"t2").start();
    }
}
@Slf4j(topic = "c.TestSunReenNum")
class TestSunReenNum extends ReentrantLock {
    private int cnt = 1;
    private final int count;
    private boolean flag = true;
    TestSunReenNum(int count) {
        this.count = count;
    }
    public void print(boolean flagN, Condition condition){
        lock();
        try {
            for (int i=0;i<count;i++){
                while (flag!=flagN){
                    condition.await();
                }
                log.debug("{}",cnt);
                cnt++;
                flag=!flag;
                condition.signalAll();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            unlock();
        }
    }
}

结果

23:51:38.603 c.TestSunReenNum [t1] - 1
23:51:38.606 c.TestSunReenNum [t2] - 2
23:51:38.606 c.TestSunReenNum [t1] - 3
23:51:38.607 c.TestSunReenNum [t2] - 4
23:51:38.607 c.TestSunReenNum [t1] - 5
23:51:38.607 c.TestSunReenNum [t2] - 6
23:51:38.607 c.TestSunReenNum [t1] - 7
23:51:38.607 c.TestSunReenNum [t2] - 8
23:51:38.607 c.TestSunReenNum [t1] - 9
23:51:38.607 c.TestSunReenNum [t2] - 10

03.问题二

三个线程交替打印abc 5次

wait/notify实现

public class TestSun2 {
    public static void main(String[] args) {
        TestSun2Num num = new TestSun2Num(5);
        new Thread(()->{
            num.print("a",1);
        }).start();

        new Thread(()->{
            num.print("b",2);
        }).start();

        new Thread(()->{
            num.print("c",0);
        }).start();
    }
}

class TestSun2Num{
    private int cnt = 1;
    private final int count;
    public TestSun2Num(int count){
        this.count=count;
    }
    public void print(String str,int flag){
        synchronized (this){
            for (int i=0;i<count;i++){
                while (cnt%3!=flag){
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.print(str);
                if (flag==0)
                    System.out.println();
                cnt++;
                this.notifyAll();
            }
        }
    }
}

结果

abc
abc
abc
abc
abc

park/unpark实现

public class TestSun2Park {
    static Thread t1;
    static Thread t2;
    static Thread t3;
    public static void main(String[] args) {
        TestSun2ParkNum num = new TestSun2ParkNum(5);
        t1 = new Thread(()->{
            num.print(1,"a",t2);
        });

        t2 = new Thread(()->{
            num.print(2,"b",t3);
        });

        t3 = new Thread(()->{
            num.print(0,"c",t1);
        });
        t1.start();
        t2.start();
        t3.start();
        LockSupport.unpark(t1);
    }
}

class TestSun2ParkNum{
    private final int count;

    TestSun2ParkNum(int count) {
        this.count = count;
    }

    public void print(int flagN,String str,Thread next){
        for (int i=0;i<count;i++){
            LockSupport.park();
            System.out.print(str);
            if (str.equals("c"))
                System.out.println();
            LockSupport.unpark(next);
        }
    }
}

结果

abc
abc
abc
abc
abc

await/signal实现

public class TestSun2Reen {
    public static void main(String[] args) {
        TestReenNum num = new TestReenNum(5);
        Condition condition1 = num.newCondition();
        Condition condition2 = num.newCondition();
        Condition condition3 = num.newCondition();
        new Thread(()->{
            num.print("a",condition1,condition2);
        }).start();

        new Thread(()->{
            num.print("b",condition2,condition3);
        }).start();

        new Thread(()->{
            num.print("c",condition3,condition1);
        }).start();

        Sleeper.sleep(1);
        num.lock();
        try {
            condition1.signal();
        }finally {
            num.unlock();
        }
    }
}

class TestReenNum extends ReentrantLock {
    private final int count;
    TestReenNum(int count) {
        this.count = count;
    }
    public void print(String str, Condition condition,Condition nextCondition){
        lock();
        try {
            for (int i=0;i<count;i++){
                condition.await();
                System.out.print(str);
                if (str.equals("c"))
                    System.out.println();
                nextCondition.signalAll();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            unlock();
        }

    }
}

结果

abc
abc
abc
abc
abc

04.需要关注的

1.我们需要熟练使用上面几种方法。
2.问题一与问题二用await/signal实现 处理的方式非常不同,可以仔细阅读 分析这两种方法

目录
相关文章
|
2月前
|
安全 数据安全/隐私保护 数据中心
Python并发编程大挑战:线程安全VS进程隔离,你的选择影响深远!
【7月更文挑战第9天】Python并发:线程共享内存,高效但需处理线程安全(GIL限制并发),适合IO密集型;进程独立内存,安全但通信复杂,适合CPU密集型。使用`threading.Lock`保证线程安全,`multiprocessing.Queue`实现进程间通信。选择取决于任务性质和性能需求。
72 1
|
18天前
|
存储 监控 算法
深入探究Java线程池:提升并发性能的利器
在当今高度并发的应用开发中,Java线程池作为一种广泛应用的并发编程技术,提供了一种优雅且高效的线程管理方案。本文深入探究Java线程池的相关技术,涵盖其核心概念、优势、常见类型(如FixedThreadPool、CachedThreadPool、SingleThreadExecutor、ScheduledThreadPool、ForkJoinPool及WorkStealingPool)、核心参数配置、异常处理与监控方法,以及性能调优的最佳实践,帮助读者更好地理解和应用线程池,从而提升并发性能。
|
2月前
|
存储 Java 调度
线程操纵术并行策略问题之Java的并行编程优势问题如何解决
线程操纵术并行策略问题之Java的并行编程优势问题如何解决
|
3月前
|
安全 Java 调度
Java并发编程:优化多线程应用的性能与安全性
在当今软件开发中,多线程编程已成为不可或缺的一部分,尤其在Java应用程序中更是如此。本文探讨了Java中多线程编程的关键挑战和解决方案,重点介绍了如何通过合理的并发控制和优化策略来提升应用程序的性能和安全性,以及避免常见的并发问题。
45 1
|
3月前
|
安全 程序员
多线程的6个综合练习
多线程的6个综合练习
25 0
|
2月前
|
Java 测试技术 容器
多线程编程基础与并发问题解决方案
多线程编程基础与并发问题解决方案
|
3月前
|
缓存 并行计算 安全
【并发编程系列一】并发编年史:线程的双刃剑——从优势到风险的全面解析
【并发编程系列一】并发编年史:线程的双刃剑——从优势到风险的全面解析
|
安全 算法 Java
【并发编程技术】「技术辩证分析」在并发编程模式下进行线程安全以及活跃性问题简析
【并发编程技术】「技术辩证分析」在并发编程模式下进行线程安全以及活跃性问题简析
69 0
【并发编程技术】「技术辩证分析」在并发编程模式下进行线程安全以及活跃性问题简析
|
安全 Java 调度
多线程强化(上)
多线程强化(上)
86 0
多线程强化(上)
|
Oracle Java 关系型数据库
多线程强化(中)
多线程强化(中)
69 0
多线程强化(中)