Java并发库(四):传统线程同步通信技术

深切怀念传智播客张孝祥老师,特将其代表作——Java并发库视频研读两遍,受益颇丰,记以后阅

04. 传统线程同步通信技术

       面试题,子线程10次与主线程100次来回循环执行50次

       下面是我刚看完面试题就暂停视频自己试着写的代码,还可以,结果完成要求了

在单次循环结束后让这个刚结束循环的线程休眠,保证另一个线程可以抢到执行权。

public class ThreadInterViewTest

{

       /**

        * 刚看到面试题没看答案之前试写

        * 子线程循环10次,回主线程循环100次,

        * 再到子线程循环10次,再回主线程循环100次

        * 如此循环50次      

        */

       publicstatic void main(String[] args)

       {

              intnum = 0;

              while(num++<50)//这种方法不好,new出来了50个线程

              {

                     newThread(new Runnable()

                                   {

                                          @Override

                                          public void run()

                                          {

                                                 circle("子线程运行", 10);

                                          }

                                   }).start();

                     try

                     {

                            //加这句是保证上边的子线程先运行,刚开始没加,主线程就先开了

                            Thread.sleep(2000);

                     }catch (InterruptedException e)

                     {

                            e.printStackTrace();

                     }

                     circle("主线程", 100);  

              }

       }

      

       publicstatic 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;

       publicsynchronized void sub()

       {

              if (bShouleSub)

此处使用while以增加程序健壮性,因为存在虚假唤醒,有时候并没有被notify就醒了。如果该方法没有同步的话,此处就更要使用while进行判断了,避免进程不同步问题


              {

                     for (int i=1; i<11; i++)

                     SOP(sub+i);

              bShouldSub= false;

              this.notify();

}

else

       this.wait();

}

       publicsynchronized void main()

       {

              if (!bShouldSub)

              {

                     for (int i=1; i<101; i++)

                     SOP(main+i);

              bShouldSub= true;

              this.notify();

}

else

       this.wait();

}

}

经验:要用到共同数据(包括同步锁)或相同算法的多个方法要封装在一个类中

       锁是上在代表要操作的资源类的内部方法中的,而不是上在线程代码中的。这样写出来的类就是天然同步的,只要使用的是同一个new出来的对象,那么这个对象就具有同步互斥特性

       判断唤醒等待标记时使用while增加程序健壮性,防止伪唤醒

public class TraditionalThreadCommunication{

 

       /**

        * @param args

        */

       publicstatic void main(String[] args) {

             

              finalBusiness business = new Business();

              newThread(

                            newRunnable() {

                                  

                                   @Override

                                   publicvoid run() {

                                  

                                          for(int i=1;i<=50;i++){

                                                business.sub(i);

                                          }

                                         

                                   }

                            }

              ).start();

             

              for(int i=1;i<=50;i++){

                     business.main(i);

              }

             

       }

 

}

 class Business {

         private boolean bShouldSub = true;

         public synchronized void sub(int i){

                while(!bShouldSub){

                       try {

                            this.wait();

                     }catch (InterruptedException e) {

                            //TODO Auto-generated catch block

                            e.printStackTrace();

                     }

                }

                     for(intj=1;j<=10;j++){

                            System.out.println("subthread sequence of " + j + ",loop of " + i);

                     }

                bShouldSub = false;

                this.notify();

         }

        

         public synchronized void main(int i){

                    while(bShouldSub){

                           try {

                                   this.wait();

                            }catch (InterruptedException e) {

                                   //TODO Auto-generated catch block

                                   e.printStackTrace();

                            }

                    }

                     for(intj=1;j<=100;j++){

                            System.out.println("mainthread sequence of " + j + ",loop of " + i);

                     }

                     bShouldSub = true;

                     this.notify();

         }

  }



public class TraditionalThreadCommunication {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		final Business business = new Business();
		new Thread(
				new Runnable() {
					
					@Override
					public void run() {
					
						for(int i=1;i<=50;i++){
							business.sub(i);
						}
						
					}
				}
		).start();
		
		for(int i=1;i<=50;i++){
			business.main(i);
		}
		
	}

}
  class Business {
	  private boolean bShouldSub = true;
	  public synchronized void sub(int i){
		  while(!bShouldSub){
			  try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		  }
			for(int j=1;j<=10;j++){
				System.out.println("sub thread sequence of " + j + ",loop of " + i);
			}
		  bShouldSub = false;
		  this.notify();
	  }
	  
	  public synchronized void main(int i){
		  	while(bShouldSub){
		  		try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		  	}
			for(int j=1;j<=100;j++){
				System.out.println("main thread sequence of " + j + ",loop of " + i);
			}
			bShouldSub = true;
			this.notify();
	  }
  }


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值