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循环

  • 相关阅读:
    FFT加速多项式乘法C语言版(基2FFT)
    springboot2中@ConfigurationProperties装载yml文件的时候调取出现值为null的解决办法
    LeetCode27-移除元素
    dom4j在解析xml文件的时候将" "解析成空格的解决办法
    LeetCode17- 电话号码的字母组合
    LeetCode19- 删除链表的倒数第N个节点
    LeetCode14- 最长公共前缀
    LeetCode20- 有效的括号
    LeetCode21- 合并两个有序链表
    MySQL单表百万数据记录分页性能优化
  • 原文地址:https://www.cnblogs.com/JSD1207ZX/p/9386230.html
Copyright © 2011-2022 走看看