问题
制作两个线程对象,要求用同步块的方式使第一个线程运行 2 次,然后将自己阻塞起来,唤醒第二个线程,第二个线 程再运行2 次,然后将自己阻塞起来,唤醒第一个线程 …… 两个线程交替执行。
思路:
类似这种同步块,一个接一个的交替的,通常会建立一个标志符,当标志符为A时候,运行第一个线程,当标志符为B时候,运行第二个线程,通过while(true)或for循环等方式使线程不断进行下去。
package night;
//制作两个线程对象,要求用同步块的方式使第一个线程运行2次,然后将自己阻塞起来,
//唤醒第二个线程,第二个线 程再运行2次,然后将自己阻塞起来,唤醒第一个线程……两个线程交替执行。
public class D1 {
// 2.创建一个标志符,用于线程的转换
private static boolean flag = true;//true->线程1;false->线程2
//1.创建两个方法
public synchronized void fun1() {
try {
while(!flag) {
this.wait();//如果是false,转为阻塞状态
}
for(int i=1;i<3;i++) {//打印2次
Thread.sleep(1000);//减缓输出的速度
System.out.println(Thread.currentThread().getName()+":"+i);
}
flag=!flag;//改truewei1
this.notifyAll();//释放其他进程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void fun2() {
try {
while(flag) {
this.wait();
}
for(int i=1;i<3;i++) {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+":"+i);
}
flag=!flag;
this.notifyAll();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
// 3.创建变量,因为D1不是static,需要自己创建一个变量
D1 obj = new D1();
// 4.创建进程1
Thread t1 = new Thread("线程1") {
@Override
public void run() {
while (true) {// 6.创建死循环来运行线程
obj.fun1();
}
}
};
// 5.创建进程2
Thread t2 = new Thread("线程2") {
@Override
public void run() {
while (true) {
obj.fun2();
}
}
};
t1.start();// 7.启动两个进程
t2.start();
}
}
程序运行过程发现的问题:
在第一次运行过程中产生异常,只输出成功两个进程
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
解决办法:
在百度上搜索该异常后得知:该异常是由于没有把判断条件放入到synchronized方法块里面;
所以讲fun1中的所有代码都装入Try中。