java环境变量设置中snchronised和锁的区别

10551人阅读
J2SE(27)
关键字:synchronized、java.util.concurrent.locks.Lock、同步、并发、锁
一、【引言】
JDK1.5之前,实现同步主要是使用synchronized,而在JDK1.5中新增了java.util.concurrent包及其两个子包locks和atomic,其中子包locks中定义了系列关于锁的抽象的类。本文主要介绍java.util.concurrent.locks的使用及其与synchronized两种方式实现同步的异同。
二、【synchronized同步】
synchronized相信很多熟悉J2SE的人都不会对这个关键字陌生,它用于实现多个线程之间的同步,一般有两种使用方式:
1、在方法上加synchronized关键字
public synchronized void f() {
//do something
}2、synchronized同步代码块
synchronized (mutex) {
// do something
}对于这两种方式又应该着重区分是否为“static”的,因为static的成员是属于类的,非staitc的是属于具体实例的,所以在使用synchronized时应该注意方法或选择的同步变量是否为static的,如下代码:
package test.
* @author whwang
下午11:19:04
public class SyncTest {
private Object mutex = new Object();
public synchronized void f1() {
synchronized (mutex) {
System.err.println(&nonstatic method f1....&);
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
public static void main(String[] args) {
SycnThread thread1 = new SycnThread(new SyncTest());
SycnThread thread2 = new SycnThread(new SyncTest());
SycnThread thread3 = new SycnThread(new SyncTest());
thread1.start();
thread2.start();
thread3.start();
class SycnThread extends Thread {
private SyncT
public SycnThread(SyncTest st) {
public void run() {
while (true) {
在main方法,创建thread1、2、3三个线程,它们都调用SyncTest的f1()方法,而方法f1()使用mutex(非static)来做同步变量,如果你的意图是实现这3个线程对方法f1的同步,那么运行的结果会让你大失所望,因为这样根本就无法使得这3个线程同步,原因在于:mutex是一个非static的成员变量,也就是说每new SyncTest(),它们的mutex变量都是不相同的。这样,对于上面这个程序来说,意味着每一个线程都使用了一个mutex来做它们各自的不同变量,如果希望上面3个线程同步,可以把mutex改为static或在创建SycnThread时,传入的SyncTest都为同一个对象即可。
还有当使用String常量或全局变量时都应该引起注意,。
三、【java.util.concurrent.locks下的锁实现同步】
自JDK1.5以为,Java提供了java.util.concurrent这个并发包,在它的子包locks中,提供了一系列关于锁的抽象的类。主要有两种锁ReentrantLockReentrantReadWriteLock,而其他的两个类,都是“辅助”类,如AbstractQueuedSynchronizer就是一个用于实现特殊规则锁的抽象类,ReentrantLock和ReentrantReadWriteLock内部都有一个继承了该抽象类的内部类,用于实现特定锁的功能。下文主要介绍:ReentrantLock和ReentrantReadWriteLock
1、可重入的锁ReentrantLock
使用ReentrantLock锁最简单的一个例子:
Lock lock = new ReentrantLock();
lock.lcok();
// do something
} finally {
lock.unlock();
上面这段代码,首先创建了一个lock,然后调用它的lock()方法,开启锁定,在最后调用它的unlock()解除锁定。值得注意的时,一般在使用锁时,都应该按上面的风格书写代码,即lock.unlock()最好放在finally块,这样可以防止,执行do something时发生异常后,导致锁永远无法被释放。
到此,还没发现Lock与synchronized有什么不同,Lock与synchronized不同之处主要体现在Lock比synchronized更灵活得多,而这些灵活又主要体现在如下的几个方法:
tryLock(long timeout, TimeUnit timeUnit)
lockInterruptibly()
//unlock()
A、trylock()方法:如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
B、tryLock(long timeout, TimeUnit timeUnit)方法:如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
是不是比synchronized灵活就体现出来了,打个不是很恰当的比分:你现在正在忙于工作,突然感觉内急,于是你跑向洗手间,到门口发现一个“清洁中,暂停使用”的牌牌。没办法,工作又忙,所以你只好先放弃去洗手间回去忙工作,可能如此反复,终于你发现可以进了,于是......
像这样的场景用synchronized你怎么实现?没办法,如果synchronized,当你发现洗手间无法暂时无法进入时,就只能乖乖在门口干等了。而使用trylock()呢,首先你试着去洗手间,发现暂时无法进入(trylock返回false),于是你继续忙你的工作,如此反复,直到可以进入洗手间为止(trylock返回true)。甚至,你非常急,你可以尝试性的在门口等20秒,不行再去忙工作(trylock(20, TimeUnit.SECONDS);)。
C、lockInterruptibly()方法
lockInterruptibly()方法的执行如下:
如果该锁定没有被另一个线程保持,则获取该锁定并立即返回,将锁定的保持计数设置为 1。
如果当前线程已经保持此锁定,则将保持计数加 1,并且该方法立即返回。
如果锁定被另一个线程保持,则出于线程调度目的,禁用当前线程,并且在发生以下两种情况之一以前,该线程将一直处于休眠状态:
&& &a、锁定由当前线程获得;
&& &b、或者其他某个线程中断当前线程。
如果当前线程获得该锁定,则将锁定保持计数设置为1。
如果当前线程:
&& &a、在进入此方法时已经设置了该线程的中断状态;
&& &b、或者在等待获取锁定的同时被中断。
则抛出 InterruptedException,并且清除当前线程的已中断状态。
即lockInterruptibly()方法允许在等待时由其它线程调用它的Thread.interrupt方法来中断等待而直接返回,这时不再获取锁,而会抛出一个InterruptedException。
D、lockInterruptibly()方法源码介绍
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
a、首先lockInterruptibly调用了内部类sync的acquireInterruptibly(1)方法,这个sync就是前面提到的AbstractQueuedSynchronizer的子类
abstract static class Sync extends AbstractQueuedSynchronizer {
}public final void acquireInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (!tryAcquire(arg))
doAcquireInterruptibly(arg);
b、在sync的acquireInterruptibly方法中,首先检查当前现场是否已经中断,如果已经中断,抛出InterruptedException异常,否则调用调用sync的doAcquireInterruptibly方法。
private void doAcquireInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.EXCLUSIVE);
boolean failed =
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = // help GC
// 抛出InterruptedException异常
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
throw new InterruptedException();
} finally {
if (failed)
cancelAcquire(node);
c、在sync的方法doAcquireInterruptibly中,关键在于检测到中断则直接退出循环(不在等待获取锁),而是直接抛出InterruptedException异常,最后在finally里调用cancelAcquire取消获锁操作。
E、除了这些方法之外,ReentrantLock还提供了很多实用的方法,这里就不再一一讲述
对于Lock,还有一个特别值得注意的地方,请看下面的代码:
Lock lock = new ReentrantLock();
lock.lock();
lock.lock();
// do something...
} finally {
lock.unlock();
可以看到上面,上面代码调用lock()方法和调用unlock()方法的次数不同,这样的一段代码执行完后,别的线程是否已经可以获取该lock锁呢?
package test.
import java.util.concurrent.locks.L
import java.util.concurrent.locks.ReentrantL
* @ClassName: Test
* @author whwang
下午02:04:04
public class Test {
public Test(String name) {
this.name =
public static void main(String[] args) {
// 这样创建一个&公平竞争&的锁
Lock lock = new ReentrantLock(true);
MyThread t1 = new MyThread(lock, new Test(&test1&));
MyThread t2 = new MyThread(lock, new Test(&test2&));
t1.start();
t2.start();
private static class MyThread extends Thread {
Lock lock =
Test test =
public MyThread(Lock lock, Test test) {
this.lock =
this.test =
public void run() {
while (true) {
// 调用两次lock
lock.lock();
lock.lock();
System.err.println(test.name + & locked...&);
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
运行的结果:
test1 locked...
test1 locked...
test1 locked...
test1 locked...
test1 locked...
test1 locked...
永远都是持有test1这个类的线程才能获取锁,其实是第一个获取锁的线程,他永远都拿着锁不放。
所以在使用Lock的时候,lock与unlock一定要配对。
2、可重入的读写锁ReentrantReadWriteLock
该锁的用法与ReentrantLock基本一样,只是ReentrantReadWriteLock实现了特殊规则(读写锁),在ReentrantReadWriteLock中有两个内部类ReentrantReadWriteLock.ReadLock和ReentrantReadWriteLock.WriteLock(实际上不止两个内部类,还有实现AbstractQueuedSynchronizer的Sync等等),这两个类分别可以使用ReentrantReadWriteLock的readLock()和writeLock()返回,该读写锁的规则是:只要没有writer,读取锁定可以由多个reader
线程同时保持,而写入锁定是独占的。下面通过一个简单的例子来了解它:
package test.
import java.util.concurrent.locks.ReentrantReadWriteL
* @ClassName: ReadWriteLockTest
* @author whwang
下午02:20:59
public class ReadWriteLockTest {
static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
public static void main(String[] args) {
// 是否可以进入多个reader - 可以
// 是否可以进入多个writer - 不可以
// 当有reader进入后, writer是否可以进入 - 不可以
// 当有writer进入后, reader是否可以进入 - 不可以
MyThread t1 = new MyThread(0, &t1&);
MyThread t2 = new MyThread(0, &t2&);
MyThread t3 = new MyThread(1, &t3&);
t1.start();
t2.start();
t3.start();
private static class MyThread extends Thread {
private String threadN
public MyThread(int type, String threadName) {
this.threadName = threadN
this.type =
public void run() {
while (true) {
if (type == 0) {
ReentrantReadWriteLock.ReadLock readLock =
readLock = lock.readLock();
readLock.lock();
System.err.println(&to read....& + threadName);
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readLock.unlock();
ReentrantReadWriteLock.WriteLock writeLock =
writeLock = lock.writeLock();
writeLock.lock();
System.err.println(&to write....& + threadName);
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
writeLock.unlock();
3、AbstractQueuedSynchronizer:如果需要自己实现一些特殊规则的锁,可以通过拓展该类来实现。
参考文档:
/view/dc281e53af090.html
/java-concurrency/index.html
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:732894次
积分:6868
积分:6868
排名:第2273名
原创:186篇
转载:37篇
评论:200条
(1)(1)(1)(2)(1)(1)(1)(1)(3)(1)(1)(12)(2)(6)(6)(10)(6)(2)(7)(3)(4)(4)(2)(2)(3)(12)(2)(13)(36)(8)(17)(27)(25)6143人阅读
基本功(29)
&&&&& 通过分析这两个用法的分析,我们可以理解java中锁的概念。一个是实例锁(锁在某一个实例对象上,如果该类是单例,那么该锁也具有全局锁的概念),一个是全局锁(该锁针对的是类,无论实例多少个对象,那么线程都共享该锁)。实例锁对应的就是synchronized关键字,而类锁(全局锁)对应的就是static synchronized(或者是锁在该类的class或者classloader对象上)。下面的文章做了很好的总结:
1.synchronized与static synchronized 的区别
&&&&&& synchronized是对类的当前实例进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块,注意这里是“类的当前实例”, 类的两个不同实例就没有这种约束了。那么static synchronized恰好就是要控制类的所有实例的访问了,static synchronized是限制线程同时访问jvm中该类的所有实例同时访问对应的代码快。实际上,在类中某方法或某代码块中有 synchronized,那么在生成一个该类实例后,改类也就有一个监视快,放置线程并发访问改实例synchronized保护快,而static
synchronized则是所有该类的实例公用一个监视快了,也也就是两个的区别了,也就是synchronized相当于 this.synchronized,而static synchronized相当于Something.synchronized.
&&&&&&&& 一个日本作者-结成浩的《java多线程设计模式》有这样的一个列子:
pulbic class Something(){
public synchronized void isSyncA(){}
public synchronized void isSyncB(){}
public static synchronized void cSyncA(){}
public static synchronized void cSyncB(){}
&&&&&& 那么,加入有Something类的两个实例a与b,那么下列组方法何以被1个以上线程同时访问呢
a. x.isSyncA()与x.isSyncB()
b. x.isSyncA()与y.isSyncA()
c. x.cSyncA()与y.cSyncB()
d. x.isSyncA()与Something.cSyncA()
&&&&& 这里,很清楚的可以判断:
a,都是对同一个实例的synchronized域访问,因此不能被同时访问
b,是针对不同实例的,因此可以同时被访问
c,因为是static synchronized,所以不同实例之间仍然会被限制,相当于Something.isSyncA()与 Something.isSyncB()了,因此不能被同时访问。
那么,第d呢?,书上的 答案是可以被同时访问的,答案理由是synchronzied的是实例方法与synchronzied的类方法由于锁定(lock)不同的原因。
个人分析也就是synchronized 与static synchronized 相当于两帮派,各自管各自,相互之间就无约束了,可以被同时访问。目前还不是分清楚java内部设计synchronzied是怎么样实现的。
结论:A: synchronized static是某个类的范围,synchronized static cSync{}防止多个线程同时访问这个 类中的synchronized static 方法。它可以对类的所有对象实例起作用。
B: synchronized 是某实例的范围,synchronized isSync(){}防止多个线程同时访问这个实例中的synchronized 方法。
2.synchronized方法与synchronized代码快的区别
&&&&&&& synchronized methods(){} 与synchronized(this){}之间没有什么区别,只是synchronized methods(){} 便于阅读理解,而synchronized(this){}可以更精确的控制冲突限制访问区域,有时候表现更高效率。
3.synchronized关键字是不能继承的
&&&&&&& 这个在一文中看到的,我想这一点也是很值得注意的,继承时子类的覆盖方法必须显示定义成synchronized。(但是如果使用继承开发环境的话,会默认加上synchronized关键字)
两种方式效率比较:
1、同步块,代码如下:
package com.bjtest.
import java.util.concurrent.CountDownL
import java.util.concurrent.ExecutorS
import java.util.concurrent.E
public class TestSynchronized {
* @param args
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final CountDownLatch cdOrder = new CountDownLatch(1);
final CountDownLatch cdAnswer = new CountDownLatch(3);
final SynchonizedClass sc = new SynchonizedClass();
for(int i=0; i&3; i++){
Runnable runnable = new Runnable(){
public void run() {
cdOrder.await();
sc.start();
cdAnswer.countDown();
}catch(Exception e){
e.printStackTrace();
service.execute(runnable);
Thread.sleep((long) (Math.random()*10000));
System.out.println(&线程& + Thread.currentThread().getName() +
&发布执行命令&);
cdOrder.countDown();
long beginTime = System.currentTimeMillis();
System.out.println(&线程& + Thread.currentThread().getName() +
&已经发送命令,正在等待结果&);
cdAnswer.await();
System.out.println(&线程& + Thread.currentThread().getName() +
&已收到所有响应结果,所用时间为:& + (System.currentTimeMillis()-beginTime));
}catch(Exception e){
e.printStackTrace();
service.shutdown();
class SynchonizedClass{
public void start() throws InterruptedException{
Thread.sleep(100);//执行其它逻辑消耗时间
synchronized(this){
System.out.println(&我运行使用了 10 ms&);
运行结果如下:
线程main发布执行命令
线程main已经发送命令,正在等待结果
我运行使用了 10 ms
我运行使用了 10 ms
我运行使用了 10 ms
线程main已收到所有响应结果,所用时间为:110
同步方法,代码如下:
package com.bjtest.
import java.util.concurrent.CountDownL
import java.util.concurrent.ExecutorS
import java.util.concurrent.E
public class TestSynchronized {
* @param args
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final CountDownLatch cdOrder = new CountDownLatch(1);
final CountDownLatch cdAnswer = new CountDownLatch(3);
final SynchonizedClass sc = new SynchonizedClass();
for(int i=0; i&3; i++){
Runnable runnable = new Runnable(){
public void run() {
cdOrder.await();
sc.start();
cdAnswer.countDown();
}catch(Exception e){
e.printStackTrace();
service.execute(runnable);
Thread.sleep((long) (Math.random()*10000));
System.out.println(&线程& + Thread.currentThread().getName() +
&发布执行命令&);
cdOrder.countDown();
long beginTime = System.currentTimeMillis();
System.out.println(&线程& + Thread.currentThread().getName() +
&已经发送命令,正在等待结果&);
cdAnswer.await();
System.out.println(&线程& + Thread.currentThread().getName() +
&已收到所有响应结果,所用时间为:& + (System.currentTimeMillis()-beginTime));
}catch(Exception e){
e.printStackTrace();
service.shutdown();
class SynchonizedClass{
public synchronized void start() throws InterruptedException{
Thread.sleep(100);//执行其它逻辑消耗时间
synchronized(this){
System.out.println(&我运行使用了 10 ms&);
运行结果如下:
线程main发布执行命令
线程main已经发送命令,正在等待结果
我运行使用了 10 ms
我运行使用了 10 ms
我运行使用了 10 ms
线程main已收到所有响应结果,所用时间为:332
两者相差:222ms。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:173448次
积分:3505
积分:3505
排名:第6625名
原创:106篇
转载:18篇
评论:458条
(1)(1)(1)(3)(5)(1)(1)(1)(2)(1)(1)(1)(3)(2)(5)(9)(8)(22)(5)(30)(6)(2)(10)(3)<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&21986人阅读
& & & & & &synchronized 是java语言关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。 &
本文直接以代码的形式来展示&synchronized 关键字的使用:
【1】synchronized &Demo1:
package com.andyidea.
* 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,
* 一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码
* 块以后才能执行该代码块。
* @author Andy.Chen
public class Thread01 implements Runnable {
public void run() {
synchronized (this) {
for(int i=0;i&3;i++){
System.out.println(Thread.currentThread().getName()+& synchronized loop &+i);
public static void main(String[] args) {
Thread01 t01 = new Thread01();
System.out.println(&Welcome to Andy.Chen Blog! \n&
+&synchronized 关键字使用 \n&
+&--------------------------&);
Thread ta = new Thread(t01,&A&);
Thread tb = new Thread(t01,&B&);
ta.start();
tb.start();
运行结果如下:
Welcome to Andy.Chen Blog!
synchronized 关键字使用
--------------------------
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
【2】synchronized &Demo2:
package com.andyidea.
* 当一个线程访问object的一个synchronized(this)同步代码块时,
* 另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
* @author Andy.Chen
public class Thread02 {
public void method01(){
synchronized (this) {
while(i++ & 3){
System.out.println(Thread.currentThread().getName() +&:&+ i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
public void method02(){
//第1种方式:当一个线程访问object的一个synchronized(this)同步代码块时,
//另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
while(j++ & 3){
System.out.println(Thread.currentThread().getName() +&:&+ j);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
//第2种方式:当一个线程访问object的一个synchronized(this)同步代码块时,
//其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。
synchronized (this) {
while(j++ & 3){
System.out.println(Thread.currentThread().getName() +&:&+ j);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
* 当一个线程访问object的一个synchronized(this)同步代码块时,
* 它就获得了这个object的对象锁。
* 结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
public synchronized void method3(){
while(k++ & 3){
System.out.println(Thread.currentThread().getName() +&:&+ k);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
public static void main(String[] args) {
final Thread02 t02 = new Thread02();
System.out.println(&Welcome to Andy.Chen Blog! \n&
+&synchronized 关键字使用 \n&
+&--------------------------&);
Thread t02A = new Thread(new Runnable() {
public void run() {
t02.method01();
Thread t02B = new Thread(new Runnable() {
public void run() {
t02.method02();
Thread t02C = new Thread(new Runnable() {
public void run() {
t02.method3();
t02A.start();
t02B.start();
t02C.start();
}运行结果如下:
Welcome to Andy.Chen Blog!
synchronized 关键字使用
--------------------------
【3】synchronized &Demo3:
package com.andyidea.
* synchronized对象锁
* @author Andy.Chen
public class Thread03 {
class InnerObject{
* 内部类方法1
private void innerMethod01(){
while(i++ & 3){
System.out.println(Thread.currentThread().getName() +&:&+ i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
* 内部类方法2
private void innerMethod02(){
while(j++ & 3){
System.out.println(Thread.currentThread().getName() +&:&+ j);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
* 外部类方法1
* @param innerObj
private void outerMethod01(InnerObject innerObj){
synchronized (innerObj) {
innerObj.innerMethod01();
* 外部类方法2
* @param innerObj
private void outerMethod02(InnerObject innerObj){
innerObj.innerMethod02();
public static void main(String[] args) {
final Thread03 t03 = new Thread03();
final InnerObject innerObj = t03.new InnerObject();
System.out.println(&Welcome to Andy.Chen Blog! \n&
+&synchronized 关键字使用 \n&
+&--------------------------&);
Thread t03A = new Thread(new Runnable() {
public void run() {
t03.outerMethod01(innerObj);
Thread t03B = new Thread(new Runnable() {
public void run() {
t03.outerMethod02(innerObj);
t03A.start();
t03B.start();
}运行结果如下:
Welcome to Andy.Chen Blog!
synchronized 关键字使用
--------------------------
1. &synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为
synchronized)。 &
2.&synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。 &
对synchronized(this)的一些理解
一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。 &
二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。 &
三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。 &
四、当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1016334次
积分:8561
积分:8561
排名:第1543名
原创:78篇
评论:456条
文章:10篇
阅读:104380
阅读:246959
(6)(2)(11)(4)(1)(3)(5)(5)(5)(12)(4)(12)(1)(5)(1)(1)(1)(3)(1)(1)(1)

我要回帖

更多关于 java正则表达式 的文章

 

随机推荐