首页 > 基础资料 博客日记

[Java] 多线程顺序打印数字

2024-04-11 12:00:05基础资料围观244

文章[Java] 多线程顺序打印数字分享给大家,欢迎收藏Java资料网,专注分享技术知识

[Java] 多线程顺序打印数字

1 前言

在阅读此篇博客之前,你需要学习:

  • Java的并发知识

该实现目的:多线程打印数字0~5,每个线程轮次打印。

2 总结

  • 线程内部设置一个order保证线程的轮次。
  • 可以利用static当做多线程的共享变量。
  • synchronized、ReentrantLock的lock()和unlock()主要保证只有一个线程正在执行内部代码
  • 涉及等待和唤醒操作时,流程结束后,避免出现线程仍然等待的情况。

3 代码

每个部分需要自己认真琢磨一下。

3.1 synchronized

抽象模型:排队询问自己是否满足条件,假如符合则操作;假如不符合则排队。

public class SynchronizedThread2 implements Runnable {

    int order;
    static int value = 0;
    static final Object object = new Object();

    public SynchronizedThread(int order) {
        this.order = order;
    }

    @Override
    @SuppressWarnings("all")
    public void run() {
        while (true) {
            synchronized (object) {
                if (value == 6) break;// 不可以放到synchronized前面

                if (value % 3 == order) {
                    System.out.println(value);
                    value++;
                }
            }
        }
        System.out.println(Thread.currentThread().getName());// 线程结束
    }
}

抽象模型:

  • 排队询问自己是否满足条件:
    • 假如不符合则等待。
    • 假如符合则操作,完成后唤醒其他等待的线程。
  • 被唤醒后排队询问。
public class SynchronizedThread1 implements Runnable {

    int order;
    static int value = 0;
    static final Object object = new Object();

    public SynchronizedThread(int order) {
        this.order = order;
    }

    @Override
    @SuppressWarnings("all")
    public void run() {
        while (true) {
            if (value == 6) break;// 可以放到synchronized后面
            synchronized (object) {
                if (value % 3 == order) {
                    System.out.println(value);
                    value++;
                    object.notifyAll();// 不可以使用notify()
                } else {
                    try {
                        object.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        System.out.println(Thread.currentThread().getName());// 线程结束
    }
}
3.2 ReentrantLock

抽象模型:排队询问自己是否满足条件,假如符合则操作;假如不符合则排队。

public class LockThread implements Runnable{
    
    int order;
    static int value = 0;
    static final ReentrantLock lock = new ReentrantLock();

    public LockThread(int order) {
        this.order = order;
    }

    @Override
    @SuppressWarnings("all")
    public void run() {
        while (true) {

            lock.lock();

            if (value == 6) {// 不可以拿到lock()前面,即使去掉unlock()
                lock.unlock();
                break;
            }

            if (value % 3 == order) {
                System.out.println(value);
                value++;
            }

            lock.unlock();
        }
        System.out.println(Thread.currentThread().getName());// 线程结束
    }
}
3.3 Condition

抽象模型:

  • 排队询问自己是否满足条件:
    • 假如不符合则到自己的位置等待。
    • 假如符合则操作,完成后唤醒下一个等待的线程。
  • 被唤醒后排队询问。
  • 会出现另外两个仍在等待问题,无法改进。
public class ConditionThread implements Runnable {

    int order;
    static final ReentrantLock lock = new ReentrantLock();
    static final List<Condition> list = new ArrayList<>(Arrays.asList(lock.newCondition(), lock.newCondition(), lock.newCondition()));
    static int value = 0;

    public ConditionThread(int order) {
        this.order = order;
    }

    @Override
    @SuppressWarnings("all")
    public void run() {
        while (true) {
            if (value == 6) {
                break;
            }

            lock.lock();

            if (value % 3 == order) {
                System.out.println(value);
                value++;
                list.get((order + 1) % 3).signal();
            }

            try {
                list.get(order).await(1L, TimeUnit.SECONDS);// 不设置时间会出现持续等待
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
        }
        System.out.println(Thread.currentThread().getName());// 线程结束
    }
}

3.4 AtomicInteger

抽象模型:疯狂轮询,只有满足条件时执行操作。

public class AtomicIntegerThread implements Runnable {
    static AtomicInteger value = new AtomicInteger();
    int order;

    public AtomicIntegerThread(int order) {
        this.order = order;
    }

    @Override
    public void run() {
        while (true) {
            int i = value.get();
            if (i == 6) break;
            if (i % 3 == order) {
                System.out.println(i);
                value.incrementAndGet();
            }
        }
        System.out.println(Thread.currentThread().getName());// 线程结束
    }
}

文章来源:https://blog.csdn.net/YANG_sena/article/details/136849608
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云