线程通信的例子 使用两个线程打印 1-100。 线程1,线程2交替打印
class Number implements Runnable{
private int number=1;
@Override
public void run() {
while (true){
synchronized (this){
if(number<=100){
System.out.println(Thread.currentThread().getName()+":"+number);
number++;
}else{
break;
}
}
}
}
}
public class CommunicationTest {
public static void main(String[] args) {
Number number = new Number();
Thread t1 = new Thread(number);
Thread t2 = new Thread(number);
t1.setName("线程一");
t2.setName("线程二");
t1.start();
t2.start();
}
}
此时都是由一个线程执行 并没有交替运行 我们需要加入wait 和notify方法 wait():一旦执行此方法当前线程进入阻塞状态 ,并释放同步监视器(锁)。 notify():一旦执行此方法就会唤醒被wait的线程 如果有多个线程被wait 会唤醒优先级高的那一个。 notifyAll():一旦执行此方法会唤醒所有被wait的现线程。
class Number implements Runnable{
private int number=1;
@Override
public void run() {
while (true){
synchronized (this){
notify();
if(number<=100){
System.out.println(Thread.currentThread().getName()+":"+number);
number++;
try {
//使得调用如下wait方法的线程进入阻塞状态
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
}
}
}
public class CommunicationTest {
public static void main(String[] args) {
Number number = new Number();
Thread t1 = new Thread(number);
Thread t2 = new Thread(number);
t1.setName("线程一");
t2.setName("线程二");
t1.start();
t2.start();
}
}
说明: 1.wait,notify,notifyAll这三个方法必须使用在同步代码块或同步方法中。 2.wait,notify,notifyAll这三个方法的调用者必须是同步代码块或同步方法中的同步监视器。 否则会出现异常。
例:我们更改锁的this对象为object
class Number implements Runnable{
private int number=1;
Object obj=new Object();
@Override
public void run() {
while (true){
synchronized (obj){
notify();
if(number<=100){
System.out.println(Thread.currentThread().getName()+":"+number);
number++;
try {
//使得调用如下wait方法的线程进入阻塞状态
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
}
}
}
会抛出异常
因为wait等方法是锁对象调用的所以必须把调用方法的对象改为obj
class Number implements Runnable{
private int number=1;
Object obj=new Object();
@Override
public void run() {
while (true){
synchronized (obj){
obj.notify();
if(number<=100){
System.out.println(Thread.currentThread().getName()+":"+number);
number++;
try {
//使得调用如下wait方法的线程进入阻塞状态
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
}
}
}
3.wait,notify,notifyAll这三个方法是定义在java.lang.object中的