`
headof
  • 浏览: 22976 次
  • 来自: ...
社区版块
存档分类
最新评论

about Thread Security

 
阅读更多
一.什么是线程安全(what).
一个类是线程安全的,当被多个线程访问时,类可以持续保证行为的正确性.
自增操作看上去是一个单独操作,然而他对于多线程来说并不是线程安全的.这个现象比较容易出现,请参照以下代码.
	private int a;
	
	@Test
	public void test() throws Exception {
		
		CountDownLatch latch = new CountDownLatch(2);
		
		Thread t1 = new Thread(new task(latch), "t1");
		Thread t2 = new Thread(new task(latch), "t2");
		
		t1.start();
		t2.start();
		latch.await();
		
		assertEquals(a,2000);
	}
	
	class task implements Runnable {
		
		private CountDownLatch latch;
		
		public task(CountDownLatch latch) {
			this.latch = latch;
		}
		
		public void run() {
			latch.countDown();
			for (int i = 0; i < 1000; i++) {
				a++;
			}
			
		}
	}
		

自增是3个操作的简写,获取当前值,加1,然后更新新值."读-改-写",而不是一个原子的操作.所以当多线程对变量a进行操作时,a不能够保证其值的准确性.另外没有同步的lazy loading不是线程安全的,下利,单例模式,希望得到的结果是不同线程调整getInstance时得到相同的对象,通过判断instance是否为null,如果不为null那么新建立一个对象,否则使用原有对象.但是事实并不正确,有可能不同线程调整时,返回不同的对象实例.
	private static LazyLoadingTester instance =null;
	
	@unThreadSafe
	public static LazyLoadingTester getInstance() {
		
		if (null == instance) {
			instance = new LazyLoadingTester();
		} 
		
		return instance;
	}


二.怎么样进行线程安全(how).
原子性:
对于例1.可以将int a 变为原子变量,例如,AtomicLong.
锁:
内部锁,synchronized,每个java对象都扮演一个用于同步的锁角色.这些内置的锁称为内部锁(intrinsic)或监视器锁(monitor locks).内部器在java中是一种互斥锁(mutual exclusion lock 也称为mutex),意味着只有一个线程可以拥有锁,当线程T1尝试请求T2占用的锁时,T1必须等待或是阻塞,直到T2释放这把锁,如果T2不释放,那么T1永远也得不到.
对于例1.也可以添加一个Object lock对象,用于内部锁对象,但是性能比AtomicLong会差.内部锁是可重进入(Reentrancy).
	static class cache<K, V> {
		public synchronized V getCache(K k) {
			return null;
		}
	}

	static class sessionCache<K,V> extends cache<K, V> {
		public synchronized V getCache(K k) {
			return super.getCache(k);
		}
	}

以上例子是不会产生死锁的,因为synchronized是可以重入的.

三.为什么要进行线程安全(why).
内部可见性:
重排序现象(recording),在单个线程中,重排序不会对结果产生影响,那么就不能保证其中操作一定按程序写定的顺序进行.
过期数据.
非原子64位操作.
没有声明为volatile的64位数据变量(double,long).JVM允许将64位读或是划分在两个32位的操作,可能出现一个值在高的32位和另一个在低32位,因些在多线程共享double,long也可能是不安全的,需要加上volatile或是锁进行保护.
锁不单单是关于同步和互斥,也是关于内存可见性
volatile 是一种同步的弱形式,只具有内存可见性.保证一个变更的更新以可预见方式告知其他线程,当一个变量被声明为volatile类型后,编译器与运行时会监视这个变量,对他的操作不会与其他内存操作一起被重排序.读一个volatile变量时,总会返回某一线程所写入的最新值.
加锁可以同时保证可见性和原子性,volatile只能保证可见性.
符合以下标准,适合使用volatile
1.写入就是不依赖变量的当前值,或者能够确保只有单一线程修改就是值.
2.变量不需要与其他状态变量参与不变约束
3.而且,访问变量时,没有其他原因需要加锁.

发布与逸出.
下面引用《Java Concurrency in Practice》两个例子.
class UnsafeStates {
    private String[] states = new String[] {
        "AK", "AL" ...
    };
    public String[] getStates() { return states; }
}

这种方法发布states会出问题,任何一个调用者都能够修改到states,states已经超出他所属的范围.
public class ThisEscape {
    public ThisEscape(EventSource source) {
        source.registerListener(
            new EventListener() {
                public void onEvent(Event e) {
                    doSomething(e);
                }
            });
        // process a;
        // process b;
    }
}

在构造ThisEscape对象时,代码执行到a处时对事件的注册已经完成,而此时构造函数并没有完成。
如正是这个时刻,事件发生,那么在doSomething中this是可见的。
那么就出现了this逸出的问题。
public class SafeListener {
    private final EventListener listener;

    private SafeListener() {
        listener = new EventListener() {
            public void onEvent(Event e) {
                doSomething(e);
            }
        };
    }

    public static SafeListener newInstance(EventSource source) {
        SafeListener safe = new SafeListener();
        source.registerListener(safe.listener);
        return safe;
    }
}

如果想在构造函数中启动线程或是注意监听器,可以使用private构造函数和一个公共的工厂方法,可以避免上面不正确的创建.
分享到:
评论

相关推荐

    深入java虚拟机(inside the java virtual machine)

    java虚拟机的运行机理的详细介绍 Inside the Java Virtual Machine Bill Venners $39.95 0-07-913248-0 Inside the Java Virtual Machine Acknowledgments Introduction Part One: Java's ...About the Author

    Professional.MFC.with.VC6

    MFC and File Security Sundry Stuff Wait Cursors Error Messages Summary Chapter 11: Writing Multithreaded Applications with MFC What's a Thread, Anyway? Thread Priorities Switching Contexts ...

    madCollection 2.5.6.0 安装版(无源码)

    package makes it easily possible to handle Shares and other Security Objects like file security or registry security. To be able to do so, this package also features functionality around Accounts and ...

    Java2核心技术卷I+卷2:基础知识(第8版) 代码

    Common Misconceptions about Java 11 Chapter 2: The Java Programming Environment 15 Installing the Java Development Kit 16 Choosing a Development Environment 21 Using the Command-Line Tools 22 ...

    Professional C# 3rd Edition

    A Note about Debugging 637 Drawing Scrollable Windows 638 World, Page, and Device Coordinates 644 Colors 645 Red-Green-Blue (RGB) Values 645 The Named Colors 646 Graphics Display Modes and the Safety ...

    python3.6.5参考手册 chm

    PEP 466: Network Security Enhancements for Python 2.7 Acknowledgements What’s New in Python 2.6 Python 3.0 Changes to the Development Process New Issue Tracker: Roundup New Documentation Format: ...

    java.核心技术.第八版 卷1

    Common Misconceptions about Java 11 Chapter 2: The Java Programming Environment 15 Installing the Java Development Kit 16 Choosing a Development Environment 21 Using the Command-Line Tools 22 ...

    system mechanic Activator v1.0

    01- AV software may warn about keygens, patches, cracks etc because of their capabilities and signatures (generating codes, etc). Sometimes also they're added to the virus/spyware database and ...

    Clever Internet Suite (SRC) v9.1.0.0

    The HttpAuthorization is not thread-safe - fixed. SFTP file permissions parsing errors were fixed, IsDir file attribute works correctly. Installer runs with errors on Windows XP - fixed. TLS engine - ...

    Visual C++ 编程资源大全(英文源码 系统)

    registry.zip Registry Class(5KB)&lt;END&gt;&lt;br&gt;39,secdesc.zip A set of classes to encapsulate the Win32 Security APIs(22KB)&lt;END&gt;&lt;br&gt;40,iconservice.zip This article demonstrates a service that uses ...

    VB编程资源大全(英文源码 API)

    If you follow the logic of the program it does teach a lot about multithreading and the necessary techniques to do this in a 'Thread Safe environmen&lt;END&gt;&lt;br&gt;37,callback.zip This small project is ...

    OSGI in Action

    Class.forName() 278 ■ Following the Thread Context Class Loader 280 8.3 Tracking down memory leaks 283 Analyzing OSGi heap dumps 283 8.4 Dangling services 287 Finding a dangling service 287 ■ ...

    金蝶BOSV6.1_业务组件API参考手册

    Packages com.kingdee.bos com.kingdee.bos.appframework.client.servicebinding com.kingdee.bos.appframework.databinding com.kingdee.bos.appframework.exception ...com.kingdee.bos.cache ...

    EurekaLog_7.5.0.0_Enterprise

    27)..Fixed: Ignored unhandled thread exceptions (when EurekaLog is disabled) now triggers default OS processing (WER) 28)..Fixed: Irnored exceptions (via per-exception/events) now bring up default RTL...

    ICS delphixe10源码版

    - About SSL - Support - Release notes - Midware - Known problems - Special thanks Legal issues: ------------- Copyright (C) 1997-2016 by Fran鏾is PIETTE Rue de Grady 24, 4053 Embourg, Belgium ...

    微软内部资料-SQL性能优化3

    The lock manager knows nothing about the resource format. It simply compares the 'strings' representing the lock resources to determine whether it has found a match. If a match is found, it knows that...

    Introduction.to.Android.Application.Development(4th,2013.12) pdf

    Security and Permissions 31 Exploring Android Applications 32 Summary 36 Quiz Questions 36 Exercises 36 References and More Information 36 2 Setting Up Your Android Development Environment 37 ...

    微软内部资料-SQL性能优化2

    Each thread has two stacks, one for kernel mode and one for user mode. A stack is an area of memory in which program procedure or function call addresses and parameters are temporarily stored. In ...

    VclZip pro v3.10.1

    This will cause files to not be decryptable by normal zip utilities thereby adding a bit of extra security. Bugs Fixed: IMPORTANT!!! Behavior of freeing the ArchiveStream (compressed stream) has ...

Global site tag (gtag.js) - Google Analytics