java 线程交替执行_Java并发 两个线程交替执行和死锁

今天看到一个题:两个线程交替打印奇数和偶数,即一个线程打印奇数,另一个打印偶数,交替打印从1到100。想了下有多重实现方法。

wait和notify方法:

1 public classOddEven {2

3 private static int i = 1;4

5 private static Object o = newObject();6

7 private static class MyThread extendsThread {8 MyThread(String name) {9 super(name);10 }11

12 public voidrun() {13 try{14 synchronized(o) {15 while (i < 100) {16 System.out.println(this.getName() + i++);17 o.notify();18 o.wait();19 }20 o.notify();21 }22 System.out.println(this.getName() + " over");23 } catch(Exception e) {24 e.printStackTrace();25 }26 }27 }28

29 public static voidmain(String[] args) {30 new MyThread("奇 ").start();31 new MyThread("偶 ").start();32

33 }34 }

---

输出:

奇 1

偶 2

奇 3

偶 4

奇 5

偶 6

奇 7

...

LockSupport实现

public classOddEvenLockSupport {private static int i = 1;private static Thread t1 = newMyThread1();private static Thread t2 = newMyThread2();public static voidmain(String[] args) {

t1.start();

t2.start();

}private static class MyThread1 extendsThread {

@Overridepublic voidrun() {while (i < 51) {

System.out.println("奇 " + i++);

LockSupport.unpark(t2);

LockSupport.park();

}

System.out.println(getName()+ " over");

LockSupport.unpark(t2);

}

}private static class MyThread2 extendsThread {

@Overridepublic voidrun() {while (i < 51) {

LockSupport.park();//顺序很重要

System.out.println("偶 " + i++);

LockSupport.unpark(t1);

}

System.out.println(getName()+ " over");

LockSupport.unpark(t1);

}

}

}

---

使用Condition

public classOddEven2 {private static Lock lock = newReentrantLock();static Condition even_c =lock.newCondition();static Condition odd_c =lock.newCondition();private static class Odd extendsThread {public voidrun() {int odd = 1;try{

lock.lock();while (odd < 100) {

System.out.println("奇 " +odd);

odd+= 2;

even_c.signal();

odd_c.await();

}

System.out.println("奇 over");

}catch(InterruptedException e) {

e.printStackTrace();

}finally{

even_c.signal();

lock.unlock();

}

}

}private static class Even extendsThread {public voidrun() {int even = 0;try{

lock.lock();while (even < 100) {

System.out.println("偶 " +even);

even+= 2;

odd_c.signal();

even_c.await();

}

System.out.println("偶 over");

}catch(InterruptedException e) {

e.printStackTrace();

}finally{

odd_c.signal();

lock.unlock();

}

}

}public static voidmain(String[] args) {newEven().start();newOdd().start();

}

}

---

另一个题,写出会导致死锁的代码:

public class DeadLock extendsThread {privateObject lock1;privateObject lock2;publicDeadLock(Object o1, Object o2) {this.lock1 =o1;this.lock2 =o2;

}public voidrun() {synchronized(lock1) {try{

TimeUnit.MILLISECONDS.sleep(500);

}catch(InterruptedException e) {

e.printStackTrace();

}synchronized(lock2) {

Q.p("end");

}

}

}public static voidmain(String[] args) {

Object o1= new Object(), o2 = newObject();newDeadLock(o1, o2).start();newDeadLock(o2, o1).start();

Q.p("main end");

}

}

---

基础回顾:

每个Java对象都拥有一个锁标记,即monitor(监视器),称为对象锁。

wait:

调用obj.wait()方法会阻塞当前线程,直到另一线程调用obj.notify()或obj.notifyAll()方法,其中obj为同一对象,当前线程必须持有obj对象锁,即必须在synchronized方法或代码块中,否则抛出IllegalMonitorStateException。调用wait方法的线程会释放对象锁。

notify:

唤醒一个正在等待该对象锁的线程,若有多个线程都在等待也只会唤醒一个。被唤醒的线程无法立即执行,直到当前线程放弃该对象锁,然后被唤醒的线程会像往常一样与任何其他线程竞争该对象锁,

该方法也必须在持有该对象锁的线程里调用,即必须在synchronized方法或代码块中,否则抛出IllegalMonitorStateException。

synchronized:

synchronized关键字标记一个方法或者代码块,当某个线程调用该对象的synchronized方法或者访问synchronized代码块时,这个线程便获得了该对象的锁,其他线程暂时无法访问这个方法,只有等待这个方法执行完毕或者代码块执行完毕,这个线程才会释放该对象的锁,其他线程才能执行这个方法或者代码块。

end

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值