代码被多线程同时的调用是安全的称之为线程安全。如果一段代码是线程安全的,那么它就不包含竞态条件。竞态条件只是发生在多线程更新共享资源的时候。因此知道Java线程什么时间执行共享的资源是重要的。
局部变量
局部变量存储在每一个线程自己的栈中。那就意味着局部变量在线程之间不会共享。那也意味着所有的局部原始变量是线程安全的。这里有一个例子:
public void someMethod(){ long threadSafeInt = 0; threadSafeInt++; }
局部对象引用
对于对象的局部引用是有点不同的。这个引用本身是不会共享的。然而,这个对象的引用是不能存储在每一个线程的栈中。所有的对象都存储在共享的堆中。
如果局部创建的对象没有逸出它创建的方法,它是线程安全的。事实上你也可以把他传递给其他的方法,并且只要传递的这个对象的它的方法对于其他的线程是不可用的。
这里有一个例子:
public void someMethod(){ LocalObject localObject = new LocalObject(); localObject.callMethod(); method2(localObject); } public void method2(LocalObject localObject){ localObject.setValue("value"); }
在这个例子中的LocalObject实例不能从这个方法中返回,也不能传递给其他的对象。那个从someMethod方法的外部是可以访问的。每一个执行someMethod方法的线程将会创建它自己的LocalObject实例,以及把它分配给localObject引用。因此这种使用是线程安全的。
事实上,这整个someMethod方法是线程安全的。甚至如果这个localObject实例被作为参数传递给相同类的其他方法,或者其他的类,它是线程安全的使用。
当然,唯一的异常,如果这些方法中的一个使用LocalObject作为参数调用,在某种程度上存储LocalObject实例,允许来自其他线程的访问。
对象成员变量
对象成员变量(字段)连同对象一起存储在堆上。因此,如果两个线程调用相同对象实例的一个方法,以及这个方法更新对象成员变量,整个方法就不是线程安全的。这里有一个例子:
public class NotThreadSafe{ StringBuilder builder = new StringBuilder(); public add(String text){ this.builder.append(text); } }
如果两个线程在相同的NotThreadSafe实例上同时的调用add方法,它就会导致竞态条件。例如:
NotThreadSafe sharedInstance = new NotThreadSafe(); new Thread(new MyRunnable(sharedInstance)).start(); new Thread(new MyRunnable(sharedInstance)).start(); public class MyRunnable implements Runnable{ NotThreadSafe instance = null; public MyRunnable(NotThreadSafe instance){ this.instance = instance; } public void run(){ this.instance.add("some text"); } }
注意这两个MyRunnable实例是怎么样分享相同的NotThreadSafe实例的。因此,当他们调用add方法的时候会导致竞态条件。
然而,如果两个线程在不同的实例上同时的调用add方法,它就不会导致竞态条件。这里是来自于之前的例子,稍微有些修改:
new Thread(new MyRunnable(new NotThreadSafe())).start(); new Thread(new MyRunnable(new NotThreadSafe())).start();
现在每一个线程都有一个他们自己的NotThreadSafe实例了,以至于他们调用这个add方法不会互相干扰。这个代码不带有竞态条件。以至于,甚至一个对象不是线程安全的,它仍然可以用这种方式使用不会导致竞态条件。
线程控制溢出规则
当尝试决定是否你的代码对某个资源访问是线程安全的时候,你可以使用下列规则:
If a resource is created, used and disposed within the control of the same thread, and never escapes the control of this thread, the use of that resource is thread safe.
资源可以是任何共享的资源,像一个对象,数组,文件,数据库连接,套接字等等。在Java中,你不能总是明确的销毁对象,以至于“销毁的”意味着对象丢失或者空的引用。
甚至如果一个对象的使用是线程安全的,如果那个对象指向了一个共享的资源像一个文件或者数据库,你的应用作为一个整体可能就不是线程安全的了。例如,如果线程1和线程2各自创建他们自己的数据库连接,连接1和连接2,每一个他们自己的连接使用是线程安全的。但是这个连接指向的数据库的使用可能就不是线程安全的。例如,如果两个线程执行像这样的代码:
check if record X exists if not, insert record X
如果两个线程同时执行这个,以及他们正在检查的这个记录X放生在相同的记录上,这里就有一个风险,他们都会最终已插入而结束。如下所示:
Thread 1 checks if record X exists. Result = no Thread 2 checks if record X exists. Result = no Thread 1 inserts record X Thread 2 inserts record X
这个也会发生在操作在文件或者其他的共享资源的线程上。因此去区分被一个线程控制的对象是否是一个资源,或者仅仅是这个资源(像数据库连接)的引用是重要的。
以上就是Java 线程全和共享资源的内容,更多相关内容请关注PHP中文网(www.php.cn)!

javaispopularforcross-platformdesktopapplicationsduetoits“ writeonce,runanywhere”哲学。1)itusesbytbytybytecebytecodethatrunsonanyjvm-platform.2)librarieslikeslikeslikeswingingandjavafxhelpcreatenative-lookingenative-lookinguisis.3)

在Java中编写平台特定代码的原因包括访问特定操作系统功能、与特定硬件交互和优化性能。1)使用JNA或JNI访问Windows注册表;2)通过JNI与Linux特定硬件驱动程序交互;3)通过JNI使用Metal优化macOS上的游戏性能。尽管如此,编写平台特定代码会影响代码的可移植性、增加复杂性、可能带来性能开销和安全风险。

Java将通过云原生应用、多平台部署和跨语言互操作进一步提升平台独立性。1)云原生应用将使用GraalVM和Quarkus提升启动速度。2)Java将扩展到嵌入式设备、移动设备和量子计算机。3)通过GraalVM,Java将与Python、JavaScript等语言无缝集成,增强跨语言互操作性。

Java的强类型系统通过类型安全、统一的类型转换和多态性确保了平台独立性。1)类型安全在编译时进行类型检查,避免运行时错误;2)统一的类型转换规则在所有平台上一致;3)多态性和接口机制使代码在不同平台上行为一致。

JNI会破坏Java的平台独立性。1)JNI需要特定平台的本地库,2)本地代码需在目标平台编译和链接,3)不同版本的操作系统或JVM可能需要不同的本地库版本,4)本地代码可能引入安全漏洞或导致程序崩溃。

新兴技术对Java的平台独立性既有威胁也有增强。1)云计算和容器化技术如Docker增强了Java的平台独立性,但需要优化以适应不同云环境。2)WebAssembly通过GraalVM编译Java代码,扩展了其平台独立性,但需与其他语言竞争性能。

不同JVM实现都能提供平台独立性,但表现略有不同。1.OracleHotSpot和OpenJDKJVM在平台独立性上表现相似,但OpenJDK可能需额外配置。2.IBMJ9JVM在特定操作系统上表现优化。3.GraalVM支持多语言,需额外配置。4.AzulZingJVM需特定平台调整。

平台独立性通过在多种操作系统上运行同一套代码,降低开发成本和缩短开发时间。具体表现为:1.减少开发时间,只需维护一套代码;2.降低维护成本,统一测试流程;3.快速迭代和团队协作,简化部署过程。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

Atom编辑器mac版下载
最流行的的开源编辑器

WebStorm Mac版
好用的JavaScript开发工具

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能