这是看传智播客的学习视频中的一道Java线程通信的面试题,我觉得挺不错的就记录下来了,方便以后自己查看。
要求用子线程和主线程实现 子线程输出20次,主线程输出50次,然后再子线程输出20次,主线程输出50次,如此循环20次
1、创建一个用于输出的业务类(Business)
class Business
{
boolean isSub = true;
/**
* 子线程的输出方法
* @param loop 总的循环次数
*/
public synchronized void sub(int loop)
{
while(!isSub) //此处使用while更好 因为根据帮助文档 线程有时候没有被唤醒会自己醒来 被称之为伪唤醒
{
try
{
this.wait();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int i = 0; i < 10; i++)
{
System.out.println("sub num:" + i + "#loop num:" + loop);
}
isSub = false;
//唤醒等待的线程
this.notify();
}
/**
* 主线程的输出方法
* @param loop 总的循环次数
*/
public synchronized void main(int loop)
{
while(isSub) //此处使用while更好 因为根据帮助文档 线程有时候没有被唤醒会自己醒来 被称之为伪唤醒
{
try
{
this.wait();
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int i = 0; i < 20; i++)
{
System.out.println("main num:" + i + "#loop num:" + loop);
}
isSub = true;
//唤醒等待的线程
this.notify();
}
}
2、在子线程和主线程中调用Business类的实例对象输出
public static void main(String[] args)
{
/**
* 创建一个Business类的实例
* 为什么这儿需要使用final,不可使用static修饰?
* final修饰后,表示此变量为只读,不可再次修改,
* 这样就保证了 内部类在引用变量的时候 与包含了自己的外部类一致
* 而static修饰的变量,是属于类级别的变量,在类被第一次访问的时候就会创建并初始化
*/
final Business business = new Business();
Thread subThread = new Thread(new Runnable()
{
@Override
public void run()
{
for(int i = 0; i < 50; i++)
{
business.sub(i);
}
}
});
subThread.start();
for(int i = 0; i < 50; i++)
{
business.main(i);
}
}