两个线程交替输出30以内的奇数偶数为例
结果类似这样
[ 张三 ]打印偶数 0
[ 李四 ]打印奇数 1
[ 张三 ]打印偶数 2
[ 李四 ]打印奇数 3
[ 张三 ]打印偶数 4
[ 李四 ]打印奇数 5
[ 张三 ]打印偶数 6
[ 李四 ]打印奇数 7
……
采用实现Runnable接口创建线程
package com.hk.java.thread;
/**
* 两个线程交替输出30以内的奇数偶数
*
* @author 浪丶荡
*
*/
public class PrintOddEven implements Runnable {
@Override
public void run() {
for (int i = 0; i <= 31; i++) {
if(i==31){//如果为31,强制结束程序
System.exit(0);
}
//名为张三的线程负责输出偶数
if (Thread.currentThread().getName().equals("张三")) {
synchronized (this) {
if (i % 2 == 0) {
System.out.println("[ "
+ Thread.currentThread().getName() + " ]打印偶数 "
+ i);
notify();// 唤醒李四
try {
wait();// 当前线程(张三)放弃执行资格,等待,直到被其他线程唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//名为李四的线程负责输出奇数
if (Thread.currentThread().getName().equals("李四")) {
synchronized (this) {
if (i % 2 == 1) {
System.out.println("[ "
+ Thread.currentThread().getName() + " ]打印奇数 "
+ i);
notify();//唤醒张三
try {
wait();// 当前线程(李四)放弃执行资格,等待,直到被其他线程唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
测试类:
public static void main(String[] args) {
PrintOddEven thereThread = new PrintOddEven();
Thread thread = new Thread(thereThread);
thread.setName("张三");
thread.start();
Thread threa = new Thread(thereThread);
threa.setName("李四");
threa.start();
}
结果
[ 张三 ]打印偶数 0
[ 李四 ]打印奇数 1
[ 张三 ]打印偶数 2
[ 李四 ]打印奇数 3
[ 张三 ]打印偶数 4
[ 李四 ]打印奇数 5
[ 张三 ]打印偶数 6
[ 李四 ]打印奇数 7
[ 张三 ]打印偶数 8
[ 李四 ]打印奇数 9
[ 张三 ]打印偶数 10
[ 李四 ]打印奇数 11
[ 张三 ]打印偶数 12
[ 李四 ]打印奇数 13
[ 张三 ]打印偶数 14
[ 李四 ]打印奇数 15
[ 张三 ]打印偶数 16
[ 李四 ]打印奇数 17
[ 张三 ]打印偶数 18
[ 李四 ]打印奇数 19
[ 张三 ]打印偶数 20
[ 李四 ]打印奇数 21
[ 张三 ]打印偶数 22
[ 李四 ]打印奇数 23
[ 张三 ]打印偶数 24
[ 李四 ]打印奇数 25
[ 张三 ]打印偶数 26
[ 李四 ]打印奇数 27
[ 张三 ]打印偶数 28
[ 李四 ]打印奇数 29
[ 张三 ]打印偶数 30
分析
notify:唤醒,唤醒对方,当线程池有多个线程出于等待状态时,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。
wait:此方法导致当前线程,将其自身放置在对象的等待集中,然后放弃此对象上的所有同步要求,也就是放弃执行权,释放占有的资源,直到被其他线程唤醒。
注意
一、测试方法不要用junit去测试,你会崩溃的!不信你试试!!!!
二、不要让所有的线程都出于等待状态,全部睡着了谁来叫醒!!!有时候整个寝室就是这样旷课的^_^