`

多线程-线程方法相同/不同下runnable使用 synchronized使用位置 购票

 
阅读更多

 

 

 

关于火车票案例中 synchronized放在代码哪里的解释

  

 

 

 

 

案例1: 火车票案例

 

特点: 多窗口下执行的同一个操作动作,使用的同一个公共数据,使用同一个runnable对象

 

package thread;

public class RunnableInUse {

	/**
	 * 1 业务类传递给 runnable类   runbanle类传递给 thread类
	 * 2 如果要执行方法是同一个业务方法,那么只需要创建一个runnable类,在这个类里面调动这个业务类的业务方法即可
	 * 3 如果要执行方法是不同业务方法,那么需要根据业务方法的不同和实际需要来创建对应个数的runnable类,后在thread类里调用不同的runnble类
	 */
	public static void main(String[] args) {
		
		MyTicket myTicket = new MyTicket();
		
		new Thread(new MyRunnable1(myTicket)).start();
		new Thread(new MyRunnable1(myTicket)).start();

	}

}

class MyRunnable1 implements Runnable{

	private MyTicket myTicket;
	public MyRunnable1(MyTicket myTicket){
		this.myTicket = myTicket;
	}
	
	@Override
	public void run() {
		myTicket.sellTicket();
	}
	
}

// 业务方法都要封装在业务类中,方法上加锁
class MyTicket {
	
	private int ticketNum = 100;
	
	public  void sellTicket(){ // 需要在方法内加锁,如果在方法头上加锁,第一个线程进来后直到执行完才能轮到第二个线程,这样就和多窗口买票违背了
		while(ticketNum > 1) {
			synchronized (this) {
				ticketNum--;
				System.out.println("出票口" + Thread.currentThread().getName() + "卖票成功,还剩下 " + ticketNum + "个票");
				
			}
		}
	}
	
 /**
  * 执行结果:
  * 出票口Thread-0卖票成功,还剩下 92个票
出票口Thread-0卖票成功,还剩下 91个票
出票口Thread-0卖票成功,还剩下 90个票
出票口Thread-0卖票成功,还剩下 89个票
出票口Thread-0卖票成功,还剩下 88个票
出票口Thread-0卖票成功,还剩下 87个票
出票口Thread-0卖票成功,还剩下 86个票
出票口Thread-0卖票成功,还剩下 85个票
出票口Thread-0卖票成功,还剩下 84个票
出票口Thread-0卖票成功,还剩下 83个票
出票口Thread-0卖票成功,还剩下 82个票
出票口Thread-0卖票成功,还剩下 81个票
出票口Thread-0卖票成功,还剩下 80个票
出票口Thread-0卖票成功,还剩下 79个票
出票口Thread-0卖票成功,还剩下 78个票
出票口Thread-0卖票成功,还剩下 77个票
出票口Thread-0卖票成功,还剩下 76个票
出票口Thread-0卖票成功,还剩下 75个票
出票口Thread-1卖票成功,还剩下 74个票
出票口Thread-1卖票成功,还剩下 73个票
出票口Thread-1卖票成功,还剩下 72个票
出票口Thread-1卖票成功,还剩下 71个票
出票口Thread-1卖票成功,还剩下 70个票
出票口Thread-1卖票成功,还剩下 69个票
  */
}

 

 

案例2: 设计4个线程,其中两个每次对j加1, 另外两个每次对j减1

 

特点: 多个线程执行的方法不同,此时需要不同的runnable对象,但是又需要共享同一个数据

 

总结: 可以用如下方式来实现:
1 将共享数据封装在另一对象中,将这个对象传递给各个runnable对象,
2 线程对共享数据的操作需要分配到这个对象上来完成,对象上的方法增加同步锁,因为所有线程使用同一个对象,因此锁栓一致。

 

 

代码:

package thread;

public class RunnableInUser2 {

	/**
	 *	两个线程对变量递增
	 *  两个线程对变量递减
	 */
	public static void main(String[] args) {
		
		AddAndDelete addAndDelete = new AddAndDelete();
		
		for(int i=0; i<4;i++){
			new Thread(new AddRunnable(addAndDelete)).start();
			new Thread(new DeleteRunnable(addAndDelete)).start();
		}
		
		
		
	}

}

class AddRunnable implements Runnable{

	private AddAndDelete addAndDelete;
	public AddRunnable(AddAndDelete addAndDelete){
		this.addAndDelete = addAndDelete;
	}
	
	@Override
	public void run() {
		addAndDelete.addOne();
	}
}

class DeleteRunnable implements Runnable{
	
	private AddAndDelete addAndDelete;
	public DeleteRunnable(AddAndDelete addAndDelete){
		this.addAndDelete = addAndDelete;
	}
	
	@Override
	public void run() {
		addAndDelete.deleteOne();
	}
}

class AddAndDelete{
	
	private int num = 0;
	
	public synchronized void addOne(){
		System.out.println("addOne, the result is" + num++);
	}
	
	public synchronized void deleteOne(){
		System.out.println("deleteOne, the result is" + num--);
	}
	/**
	 * addOne, the result is0
deleteOne, the result is1
addOne, the result is0
deleteOne, the result is1
addOne, the result is0
deleteOne, the result is1
addOne, the result is0
deleteOne, the result is1
	 */
}

  

脑图:

 



 

  • 大小: 22.4 KB
  • 大小: 36.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics