zoukankan      html  css  js  c++  java
  • 同步关键字synchronized

    同步关键字synchronized

    同步关键字synchronized使用简洁,代码可维护性好。在JDK6中,性能也比早期的JDK有很大的改进。如果可以满足程序要求,应该首先考虑这种同步方式。

             关键字synchronized一个最为常用的用法是锁定一个对象的方法:

    public synchronized void method() {}

        此时,当method()方法被调用时,调用线程必须首先获得当前对象的锁,若当前对象锁被其他线程持有,则调用线程会等待,方法结束后,对象锁会被释放。以上方法等价于:

      public void method1() {
    
           synchronized (this) {
     
    
           }
    
        }

      其次,使用synchronized还可以构造同步块,与同步方法相比,同步块可以更为精确的控制同步代码范围,缩小同步块。一个小的同步代码非常有利于锁的快进快出,从而使系统拥有更高的吞吐量。

    public void method(SomeObject so) {
    
        some code here;
    
           synchronized (so) {
    
              
               }
    
           Other code here;
    
        }

      如以上代码所示,假设在同步块前后的代码段较为耗时,而他们又无需进行同步操作,将这些代码纳入整个同步代码块就会增加锁的等待时间,而将无需同步的代码块有效的剥离,仅同步必要的代码,有利于减小锁的竞争。

      此外synchronized方法还可以用于static函数:

      public synchronized static void method() {}

      当synchronized用于static函数时,相当于将锁加到当前Class对象上,因此,所有对该方法的调用,都必须获得Class对象的锁。

      虽然synchronized可以保证对象或者代码段的线程安全,但是仅使用synchronized还不足以控制拥有复杂逻辑的线程交互。为了实现多线程间的交互,还需要使用Object对象的wait()和notify()方法。

      函数wait()可以让线程等待当前对象上的通知(notify()被调用),在wait()过程中,线程会释放对象锁。它的典型用法如下:

      synchronized (obj) {
    
          while(<等待条件>) {
    
              obj.wait();
    
             …//收到通知后,继续执行
    
             }
    
           }

      首先,在使用wait()方法前,需要获得对象锁,以上代码片段就事先获得了obj的独占锁。其次wait()方法需要在一个循环中使用,指明跳出循环的条件。在wait()方法执行时,当前线程会释放obj的独占锁,共其他线程使用。

      当等待在obj上的线程收到一个obj.notify()时,它就能重新获得obj的独占锁,并继续运行。方法notify()将唤醒一个等待在当前对象上的线程。如果当前有多个线程,那么notify()方法将随机选择其中一个。

      下面代码实现了一个阻塞队列。该队列有两个方法,分别是pop和put()。方法pop()从队列中获取第一个数据,并返回,如果队列为空,则等待一个有效的对象;方法put()将一个对象保存到队列中,并通知一个在等待中的pop()方法。

    package com.turing.currency.currencycontrolmethod.memodel;
    
     
    
    import java.util.ArrayList;
    
    import java.util.List;
    
     
    
    public class BlockQueue {
    
        private List list = new ArrayList();
    
     
    
        public synchronized Object pop() throws InterruptedException {
    
           while (list.size() == 0) {
    
               this.wait();
    
           }
    
     
    
           if (list.size() > 0) {
    
               return list.remove(0);
    
           } else
    
               return null;
    
        }
    
     
    
        public synchronized void put(Object o) {
    
           list.add(o);
    
           this.notify();
    
        }
    
    }

    注意:

        为了有效地控制线程间的协作,需要配合使用synchronized以及notify()和wait()等方法。

  • 相关阅读:
    Linus Torvalds: 成功的项目源于99%的汗水与1%的创新
    web.py入门
    Python web框架有哪些
    python and 和 or
    python 安装ssh和Scrapy
    github使用
    github的.md格式文件
    python list comprehension twos for loop 嵌套for循环
    python 中函数参数传递形式
    python MySQLdb安装和使用
  • 原文地址:https://www.cnblogs.com/ycyoes/p/5413387.html
Copyright © 2011-2022 走看看