Java -- Thread -- Collection -- 4传统线程同步通信技术
面试题,子线程10次与主线程100次来回循环执行50次
下面是我刚看完面试题就暂停视频自己试着写的代码,还可以,结果完成要求了在单次循环结束后让这个刚结束循环的线程休眠,保证另一个线程可以抢到执行权。
public class ThreadInterViewTest { /** * 刚看到面试题没看答案之前试写 * 子线程循环10次,回主线程循环100次, * 再到子线程循环10次,再回主线程循环100次 * 如此循环50次 */ public static void main(String[] args) { int num = 0; while (num++<50) { new Thread(new Runnable() { @Override public void run() { circle("子线程运行", 10); } }).start(); try { //加这句是保证上边的子线程先运行,刚开始没加,主线程就先开了 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } circle("主线程", 100); } } public static synchronized void circle(String name, int count) { for (int i=1; i<=count; i++) { System.out.println(name+"::"+i); } try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } }
张老师讲的方法:
1、将子线程和主线程中要同步的方法进行封装,加上同步关键字实现同步
2、两个线程间隔运行,添加一个标记变量进行比较以实现相互通信,加色的部分
wait notify notifyAll wait会抛出异常
class Business { private boolean bShouleSub = true; public synchronized void sub() {
//此处使用while以增加程序健壮性,因为存在虚假唤醒,有时候并没有被notify就醒了。如果该方法没有同步的话,此处就更要使用while进行判断了,避免进程不同步问题。
if (bShouleSub) { for (int i=1; i<11; i++) SOP(sub+i); bShouldSub = false; this.notify(); } else this.wait(); } public synchronized void main() { if (!bShouldSub) { for (int i=1; i<101; i++) SOP(main+i); bShouldSub = true; this.notify(); } else this.wait(); } }
经验:要用到共同数据(包括同步锁)或相同算法的多个方法要封装在一个类中 (如JSP中的cookie类里,加密algorithm以及解密algorithm都是放在一个类里)
锁是上在代表要操作的资源类的内部方法中的,而不是上在线程代码中的。这样写出来的类就是天然同步的,只要使用的是同一个new出来的对象,那么这个对象就具有同步互斥特性
判断唤醒等待标记时使用while增加程序健壮性,防止伪唤醒
浙公网安备 33010602011771号