【多线程:综合练习】

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

【多线程:综合练习】

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实现 处理的方式非常不同,可以仔细阅读 分析这两种方法

目录
相关文章
|
6月前
|
消息中间件 Dubbo Java
多线程到底用不用在业务代码上???
在当今的软件开发中,多线程技术是一种常见的优化方式,可以显著提高程序的性能和响应能力。然而,对于业务代码是否应该使用多线程,不同的开发者和专家可能会有不同的看法和经验。在这篇文章中,我们将探讨多线程在业务代码中的应用,并分析其利弊。综上所述,是否在业务代码中使用多线程需要根据具体情况来决定。如果业务系统需要同时处理多个任务,并且每个任务都可以独立地执行,那么使用多线程可以提高系统的性能和响应能力。然而,如果业务逻辑比较简单,或者系统的设计不允许使用多线程,那么使用单线程可能更加简单和安全。
120 1
|
3月前
|
监控 Java 测试技术
Java并发编程最佳实践:设计高性能的多线程系统
Java并发编程最佳实践:设计高性能的多线程系统
65 1
|
1月前
|
监控 安全 算法
线程死循环是多线程编程中的常见问题,可能导致应用性能下降甚至系统不稳定。
【10月更文挑战第6天】线程死循环是多线程编程中的常见问题,可能导致应用性能下降甚至系统不稳定。为了解决这一问题,可以通过代码审查、静态分析、添加日志监控、设置超时机制、使用锁和同步机制、进行全面测试、选用线程安全的数据结构、限制线程数量、利用现代并发库,并对团队进行培训等方法来预防和减少死循环的发生。尽管如此,多线程编程的复杂性仍需要持续监控和维护以确保系统稳定。
51 3
|
4月前
|
算法 Java 编译器
多线程线程安全问题之系统层面的锁优化有哪些常见的策略
多线程线程安全问题之系统层面的锁优化有哪些常见的策略
|
5月前
|
安全 Java 调度
Java并发编程:优化多线程应用的性能与安全性
在当今软件开发中,多线程编程已成为不可或缺的一部分,尤其在Java应用程序中更是如此。本文探讨了Java中多线程编程的关键挑战和解决方案,重点介绍了如何通过合理的并发控制和优化策略来提升应用程序的性能和安全性,以及避免常见的并发问题。
60 1
|
5月前
|
安全 程序员
多线程的6个综合练习
多线程的6个综合练习
34 0
|
5月前
|
缓存 并行计算 安全
【并发编程系列一】并发编年史:线程的双刃剑——从优势到风险的全面解析
【并发编程系列一】并发编年史:线程的双刃剑——从优势到风险的全面解析
|
存储 安全 Java
保障线程安全的设计技术
保障线程安全的设计技术
|
Oracle Java 关系型数据库
多线程强化(中)
多线程强化(中)
73 0
多线程强化(中)
|
安全 Java
多线程强化(下)
多线程强化(下)
97 0
多线程强化(下)

相关实验场景

更多
下一篇
无影云桌面