java多线程 迅雷面试题

有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC…


解题思路一:借鉴操作系统互斥的相关思想,设置了三个信号量来保证打印的顺序

但是这种方式非常麻烦,下面有参考别人的代码后,非常简洁的方法,可以直接跳到解题思路二!

public class TestMulti{
	boolean printA;  //true表示A已经打印,false表示尚未打印
	boolean printB; //同理
	boolean printC;  //同理
	public TestMulti(boolean printA,boolean printB,boolean printC){
		this.printA=printA;
		this.printB=printB;
		this.printC=printC;
}
	
	public synchronized void printA() throws InterruptedException{
		while(!printC) //仔细思考为什么要用while?
			wait();
	     System.out.print('A');
			printA=true;
			printC=false;
			notifyAll();
	}
	
	public synchronized void printB() throws InterruptedException{
		while(!printA)
			wait();
		
		
			System.out.print('B');
			printB=true;
			printA=false;
			notifyAll();
}
	
	
	public synchronized void printC() throws InterruptedException{
		while(!printB)
			wait();
			System.out.print('C');
			printC=true;
			printB=false;
			notifyAll();
}
	public static void main(String[] args){
		TestMulti test=new TestMulti(false,false,true); //保证A第一个打印
		ThreadABC a=new ThreadABC(test);
		ThreadABC b=new ThreadABC(test);
		ThreadABC c=new ThreadABC(test);
		a.setName("a");
		b.setName("b");
		c.setName("c");
		a.start();
		b.start();
		c.start();
	
}


}


class ThreadABC extends Thread{
	private TestMulti test;
	
	public ThreadABC(TestMulti test){
		
		this.test=test;
	}
	public void run(){
		for(int i=0;i<10;i++)
			try {
				if(Thread.currentThread().getName().equals("a"))
				   test.printA();
				else if(Thread.currentThread().getName().equals("b"))
					test.printB();
				else if(Thread.currentThread().getName().equals("c"))
					test.printC();
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
	}
}

解题思路二:充分理解对象锁机制后,利用对象锁来同步解决问题就非常容易了,详细思路见下面代码。


//产生对象锁的类
class XunleiLock{
	private String name="threadA";
    
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	
}

class Printer extends Thread{
	private XunleiLock lock;
	private String name;
	private int count=10;
	public Printer(String name,XunleiLock lock){  //为每一个线程配置一个锁
		this.lock=lock;
		this.name=name;
	}
	public void run(){
		while(count>0){
			synchronized(lock){ //同步代码块,保证每次只有一个线程能访问
				if(lock.getName().equals(this.name)){
					
					if(this.name.equals("threadA"))
					{
						System.out.print("A");
						lock.setName("threadB"); //切换所对象,保证打印的顺序
					}
					else if(this.name.equals("threadB"))
					{
						System.out.print("B");
						lock.setName("threadC");
					}
					else if(this.name.equals("threadC")){
                     
						System.out.print("C");
						lock.setName("threadA");
					}
					count--;
				}
					
			}
		}
	}
}


public class TestABC2 {

	public static void main(String[] args){
		XunleiLock lock=new XunleiLock();
		Printer A=new Printer("threadA",lock);
		Printer B=new Printer("threadB",lock);
		Printer C=new Printer("threadC",lock);
		A.start();
		B.start();
		C.start();
	}
}


仔细的分析上面的run方法,会发现虽然很方便的实现了顺序打印,但是每个线程需要不断的去判断自己是否获得了对象锁,想想有什么办法可以改进呢? 你想到了什么?对,就是使用wait()和notifyAll()......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值