zoukankan      html  css  js  c++  java
  • 关于多线程中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循环

  • 相关阅读:
    HDU 5744
    HDU 5815
    POJ 1269
    HDU 5742
    HDU 4609
    fzu 1150 Farmer Bill's Problem
    fzu 1002 HangOver
    fzu 1001 Duplicate Pair
    fzu 1150 Farmer Bill's Problem
    fzu 1182 Argus 优先队列
  • 原文地址:https://www.cnblogs.com/JSD1207ZX/p/9386230.html
Copyright © 2011-2022 走看看