一个面试题:两个线程,一个打印偶数,一个打印奇数,并且轮流打印,我们可以看到这种场景模式肯定是需要通过同步来实现,
实现通过的方式我们可以采用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();