关于多线程中synchronized的使用位置详解编程语言

在练习多线程之售票的时候,对于synchronized的使用有些困惑,因为我是用以下代码:

public class ThreadDemo5 { 
 
	/** 
	 * @param args 
	 */ 
	public static void main(String[] args) { 
		// TODO Auto-generated method stub 
		saleTicket_5 st = new saleTicket_5(); 
		Thread t1 = new Thread(st); 
		Thread t2 = new Thread(st); 
		Thread t3 = new Thread(st); 
		Thread t4 = new Thread(st); 
		t1.start(); 
		t2.start(); 
		t3.start(); 
		t4.start(); 
	} 
 
} 
 
class saleTicket_5 implements Runnable { 
	private int ticket = 1000; 
	Object obj = new Object(); 
 
	public void run() { 
		synchronized (obj) { 
 
			while (ticket > 0) { 
				try { 
					Thread.sleep(1000); 
				} catch (InterruptedException e) { 
					// TODO Auto-generated catch block 
					e.printStackTrace(); 
				} 
				System.out.println(Thread.currentThread().getName() + "****" 
						+ ticket--); 
			} 
		} 
	} 
} 

synchronized在此虽然将共享资源的代码块上锁,但是synchronized上锁之后,线程需要把synchronized里面的代码块执行完毕后才能释放锁,此代码块里面是一个循环,这就造成了最后的结果只有Thread-0线程在执行的情况。

之后对其进行修改:

public class ThreadDemo5 { 
 
	/** 
	 * @param args 
	 */ 
	public static void main(String[] args) { 
		// TODO Auto-generated method stub 
		saleTicket_5 st = new saleTicket_5(); 
		Thread t1 = new Thread(st); 
		Thread t2 = new Thread(st); 
		Thread t3 = new Thread(st); 
		Thread t4 = new Thread(st); 
		t1.start(); 
		t2.start(); 
		t3.start(); 
		t4.start(); 
	} 
 
} 
 
class saleTicket_5 implements Runnable { 
	private int ticket = 1000; 
	Object obj = new Object(); 
 
	public void run() { 
 
		while (true) { 
			synchronized (obj) { 
				if (ticket > 0) { 
 
					try { 
						Thread.sleep(10); 
					} catch (InterruptedException e) { 
						// TODO Auto-generated catch block 
						e.printStackTrace(); 
					} 
					System.out.println(Thread.currentThread().getName() 
							+ "****" + ticket--); 
				} else 
					break; 
			} 
 
		} 
	} 
} 

需要注意的是synchronized里面需要包含全部的共享资源,以保证对共享资源操作的原子性,另外 不要忘记退出while循环

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/17692.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论