一个面试题:两个线程,一个打印偶数,一个打印奇数,并且轮流打印,我们可以看到这种场景模式肯定是需要通过同步来实现,
实现通过的方式我们可以采用ReentrantLock来实现,也可以通过采用synchronized来实现,下边就这两种方式进行
实现,平时感觉自己代码还是敲的少,以后还是要加强代码量;
方式一:通过synchronized来实现,使用该种方式实现,有两个要点记录,一个是:我们在没有使用锁对象的wait()
方法时,调用其notify()没有影响,所以比如一段代码,上来就针对一个对象锁进行notify()是没有问题的;
两一个是:在对象锁的wait方法被唤醒后,在wait的地方继续执行,同时执行完代码块后优先拿到该对象锁,进入其wait状态;
这样技术num使用 AtomicInteger;
偶数线程:
private Object obj; private AtomicInteger num; EventThread() { } EventThread(Object obj, AtomicInteger num) { this.obj = obj; this.num = num; } @Override public void run() { while(num.get()<100) { synchronized(obj) { System.out.println("双线程wait前...."); while(num.get() % 2 != 0) { try{ obj.wait(); } catch (Exception e) { e.printStackTrace(); } } System.out.println(Thread.currentThread() + ": " + num); System.out.println("双线程wait后...."); this.num.getAndIncrement(); obj.notify(); } } }
奇数线程:
private Object obj = null; private AtomicInteger num; private boolean flag = false; OddThread() { } OddThread(Object obj, AtomicInteger num) { this.obj = obj; this.num = num; } @Override public void run() { while(num.get() < 100) { synchronized(obj) { System.out.println("单线程wait前...."); while(num.get()%2 == 0) { try { obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread() + ": " + num); System.out.println("单线程wait后...."); this.num.getAndIncrement(); obj.notify(); } } }
main函数:
AtomicInteger ai = new AtomicInteger(1); Object obj = new Object(); OddThread ot = new OddThread(obj, ai); EventThread et = new EventThread(obj, ai); Thread odd = new Thread(ot); odd.setName("单数线程"); Thread event = new Thread(et); event.setName("双数线程"); odd.setPriority(10); odd.start(); event.start();
方式二:使用ReentantLock实现;
道理是一样的;
奇数线程:
private Lock lock; private Condition odd; private Condition event; int num = 0; OddThread() { } OddThread(Lock lock, Condition odd, Condition event, int num) { this.lock = lock; this.event = event; this.odd = odd; this.num = num; } @Override public void run() { for(num=1; num<=100; num+=2) { lock.lock(); System.out.println("wait前代码执行。。。. "); System.out.println(Thread.currentThread() + ": " + num); try { odd.await(); event.signal(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("wait后代码执行。。。。 "); lock.unlock(); } }
偶数线程:
private Lock lock; private Condition odd; private Condition event; int num = 0; EventThread() { } EventThread(Lock lock, Condition odd, Condition event, int num) { this.lock = lock; this.event = event; this.odd = odd; this.num = num; } @Override public void run() { for(num=2; num<=100; num+=2) { lock.lock(); System.out.println(Thread.currentThread() + ": " + num); try { odd.signal(); event.await(); } catch (Exception e) { e.printStackTrace(); } lock.unlock(); } }
main函数:
int num = 1; Lock lock = new ReentrantLock(); Condition o = lock.newCondition(); Condition e = lock.newCondition(); OddThread ot = new OddThread(lock, o, e, num); EventThread et = new EventThread(lock, o, e, num); Thread odd = new Thread(ot); odd.setName("单数线程"); Thread event = new Thread(et); event.setName("双数线程"); odd.setPriority(10); odd.start(); event.start();