Java多线程通信 练习题:写两个线程,其中一个线程打印1-52,另一个打印A-Z,打印顺序为12A34B56C....5152Z

该练习题需要借助Java传统的线程通信的知识。

首先,我们创建了一个打印类Print,该类中分别实现了打印数字printNums()方法、以及打印字符printChars()方法。

class Print
{
	private boolean flag=false;
	public synchronized void writeNums()
	{
		try
		{
			for(int i=1;i<=26;)
			{
				//如果flag为true,说明数字已经打印了,打印数字线程阻塞
				if(flag)
				{
					wait();
				}
				else
				{
					System.out.print(i*2-1);
					System.out.print(i*2);
					//将标识设为true,表明打印数字线程已执行
					flag=true;
					i++;
					//唤醒其他线程
					notifyAll();
				}
			}
		}
		catch (InterruptedException ex)
		{
			ex.printStackTrace();
		}
	}
	public synchronized void writeChars()
	{
		try
		{
			for(int i='A';i<='Z';)
			{
				//如果flag为false,说明字符已经打印了,打印字符线程阻塞
				if(!flag)
				{
					wait();
				}
				else
				{
					System.out.print((char)i);
					//将标识设为true,表明打印字符线程已执行
					flag=false;
					i++;
					//唤醒其他线程
					notifyAll();
					
				}
			}
		}
		catch (InterruptedException ex)
		{
			ex.printStackTrace();
		}
	}
}

在该Print类中,我们通过用synchronized关键词修饰这两个方法来把这两个方法变成同步方法。由于同步方法的同步监视器为调用该方法的类实例,所以在这两个方法中可以直接使用wait()、notifyAll()方法来实现对程序的控制。方法中的flag作为一个标记,用来标记当前时候已打印数字。当程序进入printNums()方法后,如果flag为true,则表明当前已经打印数字,程序调用wait()方法阻塞;否则程序上下执行打印数字操作,当打印数字操作完成后,系统将flag设为true,然后调用notifyAll()来唤醒其他被阻塞的线程——如果系统中有打印数字线程,打印数字线程也会被唤醒,但该打印数字线程执行到该方法的wait()处时再次进入阻塞状态,只有执行打印字符方法printChars()的打印字符线程才可以向下执行。同理,打印字符线程的运行流程也是如此。

打印数字、打印字符操作都被Print类进行了封装,所以在打印数字以及打印字符线程中,只需要用Print对象调用对应的方法即可。打印数字线程如下:

class PrintNumsThread extends Thread
{
	private Print p;
	public PrintNumsThread(Print p)
	{
		this.p=p;
	}
	public void run()
	{
		p.writeNums();
	}
}

打印字符线程如下:

class PrintCharsThread extends Thread
{
	private Print p;
	public PrintCharsThread(Print p)
	{
		this.p=p;
	}
	public void run()
	{
		p.writeChars();
	}
}

最后,给出测试类:

public class PrintTest
{
	public static void main(String[] args)
	{
		Print p=new Print();
		new PrintNumsThread(p).start();
		new PrintCharsThread(p).start();
	}
}

下面展示一下我运行的结果吧!

你可能感兴趣的:(Java多线程通信 练习题:写两个线程,其中一个线程打印1-52,另一个打印A-Z,打印顺序为12A34B56C....5152Z)