同步关键字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()等方法。

时间: 2024-07-31 19:21:24

同步关键字synchronized的相关文章

线程同步关键字synchronized的作用

线程和进程的区别:  线程:是进程内部中的单一顺序控制流,一个进程拥有多个线程,多个线程共享一个进程的内存空间.   进程:是指一种"自包容"的运行程序,由操作系统直接管理.直接运行.有直接的地址空间,每个进程以开始都会消化内存. 线程同步:当二个或二个以上的进程同时访问一个资源时,为了保护资源的数据安全,只允许同一时间一个进程的访问,别的进程需要等待该进程放弃这个资源使用权时才能继续访问. 用一个列子来说明线程同步到底是怎么回事. package com.project.thread

Java中使用同步关键字synchronized需要注意的问题

在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在方法上. 关键是,不要认为给方法或者代码段加上synchronized就万事大吉,看下面一段代码: class Sync { public synchronized void test() { System.out.println("test开始.."); try { Thread.sle

java多线程学习-同步(synchronized)

(示例都是网上视频的) 假如两个线程同时调用一个方法输出字符串 public class SynchronizedTest extends Thread { public static void main(String[] args) { final SynchronizedTest st = new SynchronizedTest(); new Thread(new Runnable() { public void run() { while(true){ try { Thread.slee

轻松学会多线程(四)——synchronized同步关键字知多少

每一个对象都有一把独占锁.独占锁只限制线程对它的同步方法的访问,对非同步方法,独占锁没有意义. synchronized关键字可以作为函数的修饰符,也可以作为函数内的语句,也就是平时说的同步方法和同步代码块.如果再细分的话,synchronized可以作用域instance变量.对象引用.static函数和类上. 不过无论synchronized关键字加载方法上还是对象上,它取得的锁都是对象锁.而不是把一段代码或者函数当做锁.所以说,尽管我们对方法进行了同步,该同步方法还是有可能被其他线程的对象

5.同步关键字(synchronized)

同步关键字(synchronized): 多线程给我们提供方便的时候,也给整个编程增加了难度,尤其是对临界资源的控制,尤为重要. 一个在操作系统课上,老掉牙的事例,就把这种情况解释的明明白白. 一对夫妻共用一张银行卡,老公呢准备出去买盒烟,一查卡里还有10000元, 但在他买烟的同时,他媳妇一下子支出去9999元,现实当中肯定是买不成烟了, 但多线程中,如果不加以控制,就会造成脏读脏写. 实例: package com.xm.thread.t_19_01_27; import java.util

Java关键字synchronized详解

Java关键字synchronized详解 博客分类: Java综合 Java多线程thread互联网制造 synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A,没有的话,直接运行 它包括两种用法:synchronized 方法和 synchronized 块. 1. synchronized 方法: 通过在方法声明中

android各种同步方式(synchronized,ReentrantLock,Atomic)

5.0的多线程任务包对于同步的性能方面有了很大的改进,在原有synchronized关键字的基础上,又增加了ReentrantLock,以及各种Atomic类.了解其性能的优劣程度,有助与我们在特定的情形下做出正确的选择. 总体的结论先摆出来:  synchronized: (http://arthennala.blog.51cto.com/287631/56356/)在资源竞争不是很激烈的情况下,偶尔会有同步的情形下,synchronized是很合适的.原因在于,编译程序通常会尽可能的进行优化

Java基础-多线程-③多线程的同步之synchronized

使用线程同步解决多线程安全问题 上一篇 Java基础-多线程-②多线程的安全问题 中我们说到多线程可能引发的安全问题,原因在于多个线程共享了数据,且一个线程在操作(多为写操作)数据的过程中,另一个线程也对数据进行了操作,从而导致数据出错.由此我们想到一个解决的思路:将操作共享数据的代码行作为一个整体,同一时间只允许一个线程执行,执行过程中其他线程不能参与执行.线程同步就是用来实现这样的机制. synchronized代码块 Java中提供了synchronized关键字,将可能引发安全问题的代码

Java线程同步(synchronized)——卖票问题

卖票问题通常被用来举例说明线程同步问题,在Java中,采用关键字synchronized关键字来解决线程同步的问题. Java任意类型的对象都有一个标志位,该标志位具有0,1两种状态,其开始状态为1,当某个线程执行了synchronized(object)语句后,object对象的标志位变为0状态,直到执行完整个synchronized语句中的代码块后,该对象的标志位又回到1状态. 当一个线程执行到synchronized(object)语句的时候,先检查object对象的标志位,如果为0状态,