码迷,mamicode.com
首页 > 编程语言 > 详细

代码解说多线程互斥与同步通信问题

时间:2016-05-07 09:36:35      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:

参考

张孝详系列

场景

编写一个程序:子线程连说 3 次  “ 你愿意吗?” ,接着主线程连续回答 10次 “我愿意” ,然后子线程再说3次“你愿意吗?”,主
 线程回答“我愿意” 10次 。。。 轮流如此往复执行 10次。

分析

“连说 3 次”,“连续回答” 意味着互斥-主线程执行的时候,子线程不能执行;子线程执行的时候,主线程不能执行。

“轮流往复”意味着同步-主线程执行完一次任务(即回答10次“我愿意”),后不能继续执行,需要等待子线程执行完任务后才执行。

实验

一、线程互斥与同步通信

package cool.pengych.java.thread;

/**
 *  线程互斥与同步通信问题
 * @author pengyucheng
 */
public class ThreadCommunication
{
	/**
	 * 业务类
	 */
	final class Business
	{
		private boolean iSubExecute = true;
		
		//子线程执行
		public synchronized void sub()
		{
			while(!iSubExecute)// 这里 if 也行,但是while 使程序更健壮
			{
				try
				{
					this.wait();
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
			}
			for(int i=0;i<3;i++)
			{
				System.out.println("你愿意吗?");
			}
			iSubExecute = false;
			this.notify();
		}
		
		//主线程执行
		public synchronized void main()
		{
			while(iSubExecute) // if 也行,但是while 使程序更健壮
			{
				try
				{
					this.wait();
				} catch (InterruptedException e) 
				{
					e.printStackTrace();
				}
			}
			for(int i=0;i<10;i++)
			{
				System.out.println("我愿意!");
			}
			iSubExecute = true;
			this.notify();
		}
	}
	public static void main(String[] args)
	{
		Business business = new ThreadCommunication().new Business();
		new Thread(new Runnable()
		{
			@Override
			public void run()
			{
				for(int i = 0;i<10;i++)
				{
					business.sub();
				}
			}
		}).start();
		
		for(int i = 0;i<10;i++)
		{
			business.main();
		}
	}
}

执行结果

你愿意吗?
你愿意吗?
你愿意吗?
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
你愿意吗?
你愿意吗?
你愿意吗?
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
我愿意!
 。。。

二、对象锁互斥的两种表现形式

package cool.pengych.java.thread;
/**
 * 多线程同步:对象锁
 * 总结:java多线程同步本质上是通过对象锁-多个线程&同一个对象;形式上有代码块同步,方法同步.
 * @author pengyucheng
 */
public class ResourceShare
{
	private static Object lock = new Object();
	
	   /**
		 * 通过 this关键字同步
		 * @param name
		 */
		public  synchronized void output(String name)
		{
				for(int i=0;i<name.length();i++)
				{
					System.out.print(name.charAt(i));
				}
				System.out.println();
		}
		
		/**
		  *静态方法通过 ResourceShare.class 关键字同步 (静态方法关联的只有类的字节码对象了)
		  * @param name
		  */
		public  static synchronized void output2(String name)
		{
				for(int i=0;i<name.length();i++)
				{
					System.out.print(name.charAt(i));
				}
				System.out.println();
	   }
		
	/**
	 *  测试方法
	 * @param args
	 */
	public static void main(String[] args) 
	{
		ResourceShare rs = new ResourceShare();
		new Thread(new Runnable() {
			@Override
			public void run()
			{
				try 
				{
					Thread.sleep(1000);
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
				while(true)
				{
					// new ResourceShare().new Outputer().output("pengyucheng");
					ResourceShare.output2("pengyucheng");
				}
			}
		}).start();
		
		new Thread(new Runnable() {
			@Override
			public void run()
			{
				try 
				{
					Thread.sleep(1000);
				} catch (InterruptedException e)
				{
					e.printStackTrace();
				}
				while(true)
				{
					// new ResourceShare().new Outputer().output2("**tianlai**");
					rs.output2("**tianlai**");
				}
			}
		}).start();
	}
	
   class Outputer
	{
		/**
		 * 对象锁 lock: 这个对象必须对要同步的线程来说是同一线程
		 * 若去掉 static关键字  private Object lock = new Object(); 则本例不能同步
		 * @param name
		 */
		public void output(String name)
		{
			synchronized(lock) //代码块同步
			{
				for(int i=0;i<name.length();i++)
				{
					System.out.print(name.charAt(i));
				}
				System.out.println();
			}
		}
		
		/**
		 * 通过 this关键字同步
		 * @param name
		 */
		public synchronized void output2(String name)
		{
				for(int i=0;i<name.length();i++)
				{
					System.out.print(name.charAt(i));
				}
				System.out.println();
		}
	}
}


代码解说多线程互斥与同步通信问题

标签:

原文地址:http://blog.csdn.net/pengych_321/article/details/51330619

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!