先来说说Static的用法之后介绍线程安全的相关知识。
类(static)变量
在所有类的实例中共享
可以被标记为public或private
如果被标记为public而没有该类的实例,可以从该类的外部访问。
有时想有一个可以在类的所有实例中共享的变量。比如,这可以用作实例之间交流的基础或追踪已经创建的实例的数 量。
可以用关键字static来标记变量的办法获得这个效果。这样的变量有时被叫做class variable,以便与不共享的成员或实例变量区分开来。
Static变量在某种程度上与其它语言中的全局变量相似。Java编程语言没有这样的全局语言,但static变量是可以从类的任何实例访问的单个变量。
如果static变量没有被标记成private,它可能会被从该类的外部进行访问。要这样做,不需要类的实例,可以通过类名指向它。
类(static)方法
因为static方法不需它所属的类的任何实例就会被调用,因此没有this值。结果是,static方法不能访问与它本身的参数以及static变量分离的任何变量。访问非静态变量的尝试会引起编译错误。
也就是说static 的方法只能访问static的类。
public class Wrong {
int x;
public static void main(String args[]) {
x = 9; // COMPILER ERROR!
}
}
below is right
public class Wrong {
static int x;
public static void main(String args[]) {
x = 9; // COMPILER ERROR!
}
}
注意:
Main()是静态的,因为它必须在任何实例化发生前被顺序地访问,以便应用程序的运行。
静态方法不能被覆盖成非静态。
静态初始化程序
方法程序体中不存在的代码在static block中类可以包含该代码,这是完全有效的。当类被装载时,静态块代码只执行一次。类中不同的静态块按它们在类中出现的顺序被执行。
public class StaticInitDemo {
static int i = 5;
static {
System.out.println("Static code i= "+ i++ );
}
}
public class Test {
public static void main(String args[]) {
System.out.println("Main code: i="
+ StaticInitDemo.i);
}
}
Static code: i=5
Main code: i=6
注意:
1. Static方法和数据的单个(共享)副本是因为类和该类的所有实例而存在。通过一个实例或通过类本身可以访问static成员。
2. 非静态数据只限于实例,只能通过该实例的非静态方法对它进行访问。非静态数据定义对象之间互不相同的特点,非静态方法在它们所作用的非静态数据的基础上对每个对象的行为互不相同。
举一个简单例子说明使用:
一款鞋子的尺码是固定的,但这个型号的颜色可以有不同的,那么定义的时候,我们可以吧这款鞋子尺码定义成static的,颜色值定义成非static的,。颜色根据对象的不同而不同,其行为也根据对象的不同而不同,在它所作用的非静态数据的基础上对不同对象返回不同的颜色。
线程安全:
对于线程安全,我们先看两个例子:
class CheckoutLane
{
public static float GetTotal(Cart cart)
{
float total = 0;
for (int i = 0; i < cart.GroceryItems.Length; i++)
{
total += cart.GroceryItems[i].Price;
Thread.Sleep(100);
}
return total;
}
}
对于上面的代码,你使用多少的线程来控制,都是安全的。因为线程之间,不会共享什么资源,唯一相同的是使用了同一个逻辑。其实这是在破坏线程的前题方面下功夫,出现线程不安全的条件都没有了,那肯定就是线程安全的。
class CheckoutLane
{
static float total;
public static float GetTotal(Cart cart)
{
total = 0;
for (int i = 0; i < cart.GroceryItems.Length; i++)
{
total += cart.GroceryItems[i].Price;
Thread.Sleep(100);
}
return total;
}
}
对于上面的这个例子,不是线程安全的,因为共享了static float total;这个资源,而各个线程都随机都被调用,可以任意修改total这个数据。这个,就正如多个收银员共享柜台,任意执行收银操作一样。
class CheckoutLane
{
static float total;
static object synchLock = new object();
public static float GetTotal(Cart cart)
{
lock(synchLock)
{
total = 0;
for (int i = 0; i < cart.GroceryItems.Length; i++)
{
total += cart.GroceryItems[i].Price;
Thread.Sleep(100);
}
return total;
}
}
}
上面的代码是线程安全的,使用了lock关键字,可以达到一个线程强占资源的效果。这时,synchLock就作为了共享的资源,被某一个线程锁住了。
分享到:
相关推荐
在多线程环境下,线程安全的单例模式尤为重要,因为如果不正确实现,可能会导致多个线程同时创建多个实例,违反了单例模式的基本原则。 在Java中,单例模式通常有以下几种实现方式: 1. 饿汉式(静态常量): ...
在Java编程中,多线程安全集合是程序员在并发环境下处理数据共享时必须考虑的关键概念。这些集合确保了在多个线程访问时的数据一致性、完整性和安全性,避免了竞态条件、死锁和其他并发问题。Java提供了一系列的线程...
线程安全问题的根本原因在于`static`属性`a`的访问没有进行任何同步控制。在多线程环境下,对共享资源的访问需要通过synchronized关键字、Lock接口或其他并发工具来确保原子性和可见性。在上述代码中,可以使用`...
### 线程安全的单例模式详解 #### 一、单例模式简介 单例模式(Singleton Pattern)是软件开发中最常用的创建型设计模式之一,它的主要目标是确保一个类只有一个实例,并提供一个全局访问点。单例模式在很多场景下...
然而,ArrayList本身并不是线程安全的,这意味着在多线程环境中,多个线程同时访问和修改ArrayList时,可能会出现数据不一致或者竞态条件等问题。本测试着重于分析ArrayList在并发环境下的行为,并探讨如何确保其...
线程安全的单例模式在多线程环境下尤其重要,因为不正确的实现可能导致多个线程创建多个实例,这违反了单例模式的基本原则。C++11引入了新的特性,如std::mutex和std::call_once,使得实现线程安全的单例模式变得...
Java 非线程安全类变线程安全类 Java 中的非线程安全类是指有状态的类,即有属性的类,这些类在多线程环境下可能会出现线程安全问题。非线程安全类的例子可以是 NotThreadSafe 类,该类有一个共享变量 state,当多...
### Java并发中的线程安全性 #### 1. 引言 随着Java技术的发展以及多核处理器的普及,Java并发编程成为软件开发中的一个重要领域。Java并发控制问题是国内外学者研究的热点之一,特别是在J2SE 1.5版本中引入了`...
在Java编程语言中,线程安全是多线程环境下程序正确执行的重要概念。"synchronized"关键字和单例模式是确保线程安全的两种常见手段。本文将详细探讨这两个概念及其在实现线程安全中的作用。 一、synchronized关键字...
### 线程安全单例 #### 背景与概念 在软件开发过程中,单例模式是一种常用的设计模式,其目的是确保一个类只有一个实例,并提供一个全局访问点。单例模式的应用非常广泛,比如数据库连接池管理、日志对象等场景。...
然而,多线程环境下的数据共享和操作可能会引发线程安全问题,如果不正确处理,可能导致数据不一致、程序崩溃等严重后果。本示例将探讨如何在Java中实现一个线程安全的订票系统。 首先,我们要理解什么是线程安全。...
#### 变量种类与线程安全 1. **静态变量** - 静态变量是类级别的变量,由类的所有实例共享。 - 如果静态变量被多个线程同时修改,可能会导致线程不安全。 **静态变量线程不安全测试代码** ```java package ...
在Java多线程编程中,线程安全问题是非常关键的概念,它涉及到多个线程访问共享资源时可能出现的数据不一致或异常情况。本题主要通过两个练习题来加深对线程安全的理解。 ### 练习题1:新年倒计时 #### 题目描述 ...
### Java多线程—解决单例模式中的懒汉式的线程安全问题 #### 一、单例设计模式的线程安全问题 ##### (1)饿汉式没有线程安全问题 **饿汉式**是一种非常典型的单例模式实现方式,其特点是在类加载时就完成了实例...
本主题将详细探讨如何使用Qt的QThread类来创建和管理线程,并且安全地结束线程,同时结合QMutex进行线程同步,以及如何实现Qt的单例模式。 1. **QThread的使用**: - **创建线程**: 在Qt中,创建线程通常是通过...
### JAVA多线程与线程安全实践:基于HTTP协议的断点续传 #### 多线程基础 在深入探讨如何实现基于HTTP协议的断点续传之前,我们首先需要了解一些关于Java多线程的基础知识。Java多线程是Java编程语言的一个核心...
深入研究Servlet线程安全性问题,我们首先需理解Servlet在多线程环境下的行为与潜在的风险。Servlet作为一种在服务器端处理HTTP请求的技术,被设计成能够高效处理并发请求,这一特性使其在多用户环境下表现优越。...
Java多线程编程中,线程安全问题是常见的挑战,特别是在并发环境下,多个线程可能会同时访问和修改同一份共享资源,导致数据不一致。为了解决这个问题,Java提供了同步机制,其中一种常用的方式就是同步代码块...