【java】wait实现多线程顺序打印

        java中多线程是并发编程的重要概念,它允许程序同时执行多个任务。通过多线程并行处理,系统能够更好的利用CPU和其他资源。但在有些情况下,需要保证多线程的顺序执行。通过wait、notity、notifyAll方法可以实现线程有序执行。

1、题目1:线程1 打印1,线程2打印2,线程3打印3。通过wait方法实现多线程顺序打印结果为123

1.分析

wait、notify、notifyAll是实现线程间通信和同步的,需谨慎的处理锁对象的获取和释放。可以通过共享的锁对象来控制线程的打印。每个线程在打印完成后,通知其他线程继续执行,由于顺序执行,还需一个表示当前应该打印哪个数字的标识(如 一个整数索引)。

2.逻辑

a.首选通过while循环检查index是否等于要打印的期望值number。

b.若不等,调用lock.wait方法使当前线程等待,直到其打印线程通过lock.notifyAll方法唤醒。

c.当index = number时,打印数字,并对index累加

d.使用lock.notifyAll方法唤醒所有在等待的线程

3.代码

代码实现多线程顺序打印

public class PrintOrder{
   //共享锁对象
	private final Object lock = new Object();
    //实际打印数字的索引
	private int index = 1;

	public void print(int number){
		synchronized(lock){
			//等待当前索引与线程要打印的数字匹配
			while(index != number){
				try{
					lock.wait();
				}catch(InterruptedException e){
					//重新设置中断状态
					Thread.currentThread().interrupt();
					return;
				}
			}
			system.out.print(number);

			//更新索引并通知其他线程
			index++;
			//确保所有等待的线程都被唤醒
			lock.notifyAll();
		}
	}

	public static void main(String[] args){
		PrintOrder print = new PrintOrder();

		Thread t1= new Thread(() -> print.print(1));
		Thread t2= new Thread(() -> print.print(2));
		Thread t3= new Thread(() -> print.print(3));

		t1.start();
		t2.start();
		t3.start();
	}
}

运行结果:123

4.代码解析

锁对象(lock):用来同步print方法中同步代码块,确保在任何时候只有一个线程可以访问这个代码块。

执行顺序:

a.首选通过while循环检查index是否等于要打印的期望值number。

b.若不等,调用lock.wait方法使当前线程等待,直到其打印线程通过lock.notifyAll方法唤醒。

c.当index = number时,打印数字,并对index累加

d.使用lock.notifyAll方法唤醒所有在等待的线程

线程执行(t1、t2、t3):每个线程都调用print方法,分别尝试打印1、2、3

2、题目2:在题目1的基础上,要求线程1、线程2、线程3无限循环打印出123123123....

题目2与题目1在问题分析和逻辑上基本保持一致,题目2在题目1的基础上需要解决线程无限循环的问题。

1、代码
public class PrintNumbers {  
    private int number = 1; // 控制打印的变量  
    private final Object lock = new Object(); // 锁对象  
  
    public void printNumber(int n) {  
        synchronized (lock) {  
            while (number != n) {  
                try {  
                    lock.wait(); // 如果当前数字不是n,则等待  
                } catch (InterruptedException e) {  
                    Thread.currentThread().interrupt(); // 处理中断  
                }  
            }  
              
            // 打印数字  
            System.out.println(Thread.currentThread().getName() + ": " + number);  
              
            // 更新数字并通知其他线程  
            number = (number % 3) + 1; // 循环1, 2, 3  
            lock.notifyAll(); // 唤醒所有等待的线程  
        }  
    }  
  
    public static void main(String[] args) {  
        PrintNumbers pn = new PrintNumbers();  
  
        Thread t1 = new Thread(() -> {  
            while (true) {  
                pn.printNumber(1);  
            }  
        }, "Thread-1");  
  
        Thread t2 = new Thread(() -> {  
            while (true) {  
                pn.printNumber(2);  
            }  
        }, "Thread-2");  
  
        Thread t3 = new Thread(() -> {  
            while (true) {  
                pn.printNumber(3);  
            }  
        }, "Thread-3");  
  
        t1.start();  
        t2.start();  
        t3.start();  
    }  
}
2、代码分析

基于上面代码分析,代码流程与题目1的逻辑基本一致,但也存在一些差异。

a.当number= n时,打印数字,并对number % 后取模后再+1。

b.创建线程使,在Thread类带参构造方法中while(true)实现线程的无限打印。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值