导航:首页 > 编程语言 > java静态方法多线程

java静态方法多线程

发布时间:2023-05-02 02:54:18

1. java多线程并发去调用一个类的静态方法,有什么问题

总的结论:java是线程安全的,即对任何方法(包括静态方法)都可以不考虑线程冲突,但有一个前提,就是不能存在全局变量。如果存在全局变量,则需要使用同步机制。x0dx0ax0dx0a如下通过一组对比例子从头讲解:x0dx0a 在多线程中使用静态方法会发生什么事?也就是说多线程访问同一个类的static静态方法会发生什么事?是否会发生线程安全问题?x0dx0apublic class Test {x0dx0a public static void operation(){x0dx0a // ... do somethingx0dx0a }x0dx0a}x0dx0a 事实证明只要在静态函数中没有处理多线程共享数据,就不存在着多线程访问同一个静态方法会出现资源冲突的问题。下面看一个例子:x0dx0apublic class StaticThread implements Runnable {x0dx0a @Overridex0dx0a public void run() {x0dx0a // TODO Auto-generated method stubx0dx0a StaticAction.print();x0dx0a }x0dx0a public static void main(String[] args) {x0dx0a for (int i = 0; i < 100; i++) {x0dx0a new Thread(new StaticThread()).start();x0dx0a }x0dx0a }x0dx0a}x0dx0apublic class StaticAction {x0dx0a public static int i = 0;x0dx0a public static void print() {x0dx0a int sum = 0;x0dx0a for (int i = 0; i < 10; i++) {x0dx0a System.out.print("step " + i + " is running.");x0dx0a sum += i;x0dx0a }x0dx0a if (sum != 45) {x0dx0a System.out.println("Thread error!");x0dx0a System.exit(0);x0dx0a }x0dx0a System.out.println("sum is " + sum);x0dx0a }x0dx0a}x0dx0a 实际执行的结果显示各个线程对静态方法的访问是交叉执行的,但是这并不影响各个线程静态方法print()中sum值的计算。也就是说,在此过程中没有使用全局变量的静态方法在多线程中是安全的,静态方法是否引起线程安全问题主要看该静态方法是否对全局变量(静态变量static member)进行修改操作。x0dx0a 在多线程中使用同一个静态方法时,每个线程使用各自的实例字段(instance field)的副本,而共享一个静态字段(static field)。所以说,如果该静态方法不去操作一个静态成员,只在方法内部使用实例字段(instance field),不会引起安全性问题。x0dx0a 但是,如果该静态方法操作了一个静态变量,则需要静态方法中采用互斥访问的方式进行安全处理。我们来看一下没有使用互斥访问的话会产生怎样的问题:public class StaticAction {x0dx0a public static int i = 0;x0dx0a public static void incValue() {x0dx0a int temp = StaticAction.i;x0dx0a try {x0dx0a Thread.sleep(1);x0dx0a } catch (Exception e) {x0dx0a e.printStackTrace();x0dx0a }x0dx0a temp++;x0dx0a StaticAction.i = temp;x0dx0a }x0dx0a}x0dx0apublic class StaticThread implements Runnable {x0dx0a @Overridex0dx0a public void run() {x0dx0a // TODO Auto-generated method stubx0dx0a StaticAction.incValue();x0dx0a }x0dx0a public static void main(String[] args) {x0dx0a for (int i = 0; i < 100; i++) {x0dx0a new Thread(new StaticThread()).start();x0dx0a }x0dx0a try {x0dx0a Thread.sleep(1000); //预留足够的时间让上面的线程跑完x0dx0a } catch (Exception e) {x0dx0a e.printStackTrace();x0dx0a }x0dx0a System.out.println(StaticAction.i);x0dx0a }x0dx0a}x0dx0a 实际运行结果显示i值为随机的数字。为了实现互斥访问,这时我们需要加入一个synchronized关键字。代码修改如下:x0dx0apublic class StaticAction {x0dx0a public static int i = 0;x0dx0a public synchronized static void incValue() {x0dx0a int temp = StaticAction.i;x0dx0a try {x0dx0a Thread.sleep(1);x0dx0a } catch (Exception e) {x0dx0a e.printStackTrace();x0dx0a }x0dx0a temp++;x0dx0a StaticAction.i = temp;x0dx0a }x0dx0a}x0dx0apublic class StaticThread implements Runnable {x0dx0a @Overridex0dx0a public void run() {x0dx0a // TODO Auto-generated method stubx0dx0a StaticAction.incValue();x0dx0a }x0dx0a public static void main(String[] args) {x0dx0a for (int i = 0; i < 100; i++) {x0dx0a new Thread(new StaticThread()).start();x0dx0a }x0dx0a try {x0dx0a Thread.sleep(1000);x0dx0a } catch (Exception e) {x0dx0a e.printStackTrace();x0dx0a }x0dx0a System.out.println(StaticAction.i);x0dx0a }x0dx0a}x0dx0a 运行结果则必然是100。x0dx0a 加入synchronized关键字的静态方法称为同步静态方法。x0dx0a 在访问同步静态方法时,会获取该类的“Class”对象,所以当一个线程进入同步的静态方法中时,线程监视器获取类本身的对象锁,其它线程不能进入这个类的任何静态同步方法。它不像实例方法,因为多个线程可以同时访问不同实例同步实例方法。这个其实就是操作系统中的用信号量实现进程的互斥与同步问题,如果涉及在同一个类中有多个静态方法中处理多线程共享数据的话,那就变成用信号量解决生产者-消费者问题。也就是说,静态方法是一份临界资源,对静态方法的访问属于进入临界区;对静态变量的修改是一份临界资源,对静态变量的修改属于进入临界区。

2. java如何实现静态变量多线程安全问题

public class A { public void method01(){ //dosomething } public void method02(){ //dosomething } //public void method03(){ public static void method03(){ // 静态方法里才可以有今天变量 static Map map = new TreeMap(); static String x=“”; // 如果你的 method4,5,6是异步的, 5,6得到的值就是不确定的, // 有可能是4之前的值,也有可能是4的赋值 method4(){ 这里面会给map和x赋值 } method5(){ 这里面会用到map和x } method6(){ 这里面会用到map和x } }}

3. Java中关于static成员方法的线程安全问题

都同时调用了,怎么还不是多线环境睁烂下呢?但是就算是同时调用,如果没有共享变量,有共享变锋早改量,但变量是final(引用类型除外)或者是线程安全类(Concurrent包下的,也可以)就不会存在并发问题。
public
class
TestUtil()
{
private
static
int
i
=
0
public
static
int
a
(){
return
i++;//会有并发问题
}
public
static
int
b()
{
int
i
=
0;
return
i++;//不会有并发问题
}
}
方法是否存在并发问题,判断是否有竞态条件就银判好了

4. java中多线程中的static和voilate

static不能实现多线程共享,它的作用是让同一个类的不同对象,共用同一个变量,与线程无关。如果有多个线程同时修改一个静态变量,同样会有不同步问题。

5. 初学Java多线程:使用Synchronized块同步方法

synchronized关键字有两种用法 第一种就是在《使用Synchronized关键字同步类方法》一文中所介绍的直接用在方法的定义中 另外一种就是synchronized块 我们不仅可以通过synchronized块来同步一个对象变量巧顷 也可以使用synchronized块来同步类中的静态孝宽陆方法和非静态方法

synchronized块的语法如下

public void method()

{

… …

synchronized(表达式)

{

… …

}

}

一 非静态类方法的同步

从《使用Synchronized关键字同步类方法》一文中我们知道使用synchronized关键字来定义方法就会锁定类中所有使用synchronzied关键字定义的静态方法或非静态方法 但这并不好理解 而如果使用synchronized块来达到同样的效果 就不难理解为什么会产生这种效果了 如果想使用synchronized块来锁定类中所有的同步非静态方法 需要使用this做为synchronized块的参数传入synchronized块国 代码如下

通过synchronized块同步非静态方法

public class SyncBlock

{

public void method ()

{

synchronized(this) // 相当于对method 方法使用synchronized关键字

{

… …

}

}

public void method ()

{

synchronized(this) // 相当于对method 方法使用synchronized关键字

{

… …

}

}

public synchronized void method ()

{

… …

}

}

在上面的代码中的method 和method 方法中使用了synchronized块 而第 行的method 方法仍然使用synchronized关键字来定义方法 在使用同一个SyncBlock类实例时 这三个方法只要有一个正在执行 其他两个方法就会因未获得同步锁而被阻塞 在使用synchronized块时要想达到和synchronized关键字同样的效果 必须将所有的代码都写在synchronized块中 否则 将无法使当前方法中的所有代码和其他的方法同步

除了使用this做为synchronized块的参数外 还可以使用SyncBlock this作为synchronized块的参数来达到同样的效果

在内类(InnerClass)的方法中使用synchronized块来时 this只表示内类 和外类(OuterClass)没有关系 但内类的非静态方法可以和外类的非静态方法同步 如在内类InnerClass中加一个method 方法 并使method 方法和SyncBlock的三个方法同步 代码如下

使内类的非静态方法和外类的非静态方法同步

public class SyncBlock

{

… …

class InnerClass

{

public void method ()

{

synchronized(SyncBlock this)

{

… …

}

}

}

… …

}

在上面SyncBlock类的新版本中 InnerClass类的method 方法和SyncBlock类的其他三个方法同步 因此 method method method 和method 四个方法在同一时间巧手只能有一个方法执行

Synchronized块不管是正常执行完 还是因为程序出错而异常退出synchronized块 当前的synchronized块所持有的同步锁都会自动释放 因此 在使用synchronized块时不必担心同步锁的释放问题

二 静态类方法的同步

由于在调用静态方法时 对象实例不一定被创建 因此 就不能使用this来同步静态方法 而必须使用Class对象来同步静态方法 代码如下

通过synchronized块同步静态方法

public class StaticSyncBlock

{

public static void method ()

{

synchronized(StaticSyncBlock class)

{

… …

}

}

public static synchronized void method ()

{

… …

}

}

在同步静态方法时可以使用类的静态字段class来得到Class对象 在上例中method 和method 方法同时只能有一个方法执行 除了使用class字段得到Class对象外 还可以使用实例的getClass方法来得到Class对象 上例中的代码可以修改如下

使用getClass方法得到Class对象

public class StaticSyncBlock

{

public static StaticSyncBlock instance;

public StaticSyncBlock()

{

instance = this;

}

public static void method ()

{

synchronized(instance getClass())

{

}

}

}

在上面代码中通过一个public的静态instance得到一个StaticSyncBlock类的实例 并通过这个实例的getClass方法得到了Class对象(一个类的所有实例通过getClass方法得到的都是同一个Class对象 因此 调用任何一个实例的getClass方法都可以) 我们还可以通过Class对象使不同类的静态方法同步 如Test类的静态方法method和StaticSyncBlock类的两个静态方法同步 代码如下

Test类的method方法和StaticSyncBlock类的method method 方法同步

public class Test

{

public static void method()

{

synchronized(StaticSyncBlock class)

{

}

}

}

lishixin/Article/program/Java/gj/201311/27374

6. java多线程中,如何给静态变量(如List)加锁/同步

使用synchronized关键字同步方法就可以了。
public class Foo2 {
private int x = 100;
public int getX() {
return x;
}
//同步方法
public synchronized int fix(int y) {
x = x - y;
System.out.println("线程"+Thread.currentThread().getName() + "运行结束,减少“" + y + "”,当前值为:" + x);
return x;
}
}

7. java多线程调用静态方法安全吗

这要看静态方法中有没有操作静态成员变量了,看代码吧

{
staticintnum=0;

publicstaticvoidaddOne()throwsInterruptedException{
for(inti=0;i<=10;i++){
num+=i;
}
System.out.println(Thread.currentThread().getName()+"-"+num);
num=0;
}
}

如上面代码所示,当单线程运行情况下是输出正常的,num最后应该输出55,但是在多线程情况下,则会出现每个线程输出的num不一样的情况,这是因为num是静态成员变量,为多个线程所共享的,有可能会出现一个线程的num值还没有重新赋值为0,另外一个线程已经读取到num的累加后的值,所以说,多线程情况下,静态方法中如果操作静态成员变量,那这个静态方法就不是线程安全的

8. JAVA中当多个线程同步调用static方法或static变量的时候会产生冲突吗

静态块的资源访问谨物信消时不会有冲突的,
单例么,比如车场是单例祥坦液的,但是里面有很多车,每个客户来都可以分配单独的一辆车,所以多线程同步 也是不会冲突的

9. 初学Java的关键主要是什么

在计算机快速发展的今天,计算机行业的人才需求量也是越来越多,很多人开始选择从计算机方法进行发展。很多人都知道,计算机方面的知识是比较复杂的,学习起来会遇到很多的困难,Java语言是软件开发中使用最多的语言,那么对于初学者应该如何进行选择呢?学习Java语言开发的过程中,什么是最关键的?应该如何进行学习?下面电脑培训为大家介绍初学Java的关键。

一、学习静态方法和属性

在学习Java开发中,静态语言和属性的使用是非常关键的,主要是用于描述某一类对象群体的特征,而不是属于单个对象的特征。在Java中需要大量的使用静态方法和属性,这个技巧是非常关键的,但是有一个缺点就是这种语言不能被频繁的使用。在学习过程中,静态方法和属性对于后期理解类和对象内容有很大的帮助,在进行Java开发时,静态方法和属性的使用是非常频繁的。


二、重视接口问题

类继承在早期面向对象的应用程序中大量使用。随着软件工程理论的不断发展,人们开始意识到继承的诸多缺点,并开始尝试使用聚合而不是继承。IT培训认为能够很好的解决可扩展性的软件工程的重要原则的抽象描述,并且还能直接使用的工具是界面。接口已经逐渐成为近年来Java编程的核心。

三、集合框架的学习

Java进行描述复杂数据结构的主要方式是集合框架。Java没有任何指针,而是复杂数据结构的复杂集合,例如数组和对象数组。学习这些数据结构的描述对于应正滑悔用程序编程至关重要,特别是在涉及服务器端的3层结构编程时。此时,昌平北大青鸟发现举正可能出现程序员无法再使用诸如数据库结果集之类的结构来描述数据的情况。

四、多线程的理解机理

在进行学习Java语言的时候,很多人对多线程程序的编写非常感兴趣,毕竟这是对逻辑能力最大的挑战。但是在进行开发的过程中,其实很多应用都会不需要使用多线程程序,并且很多厉害的应用程序员在编写代码的过程中也是不需要使用多线程的。一般情况下让闷,北大青鸟北京计算机学院发现多线程机制主要是使用到基础平台中。


10. JAVA中static 方法在多线程环境下的运用,求解。

static相当与在你的系统内存开辟出一块固定内存,整个项目都可以访问并且修改他
比如 static int a=0;
假设同时开启3个线层
你在线层a里面核慧a=1;
线程b:a=2;
线程c:a=3;
因睁或为我们并不知道那个线程会悉氏伍最后结束 所以没办法判断a=?

阅读全文

与java静态方法多线程相关的资料

热点内容
python编译器怎么清除 浏览:73
linux全局socks代理 浏览:611
php微信抽奖 浏览:771
压缩算法嵌入式移植 浏览:531
php新手小例子 浏览:233
按照医生的算法一周是几天 浏览:805
三次b样条曲线算法 浏览:924
java7特性 浏览:555
爱山东app小学报名怎么知道报没报上 浏览:458
android获取wifi信号 浏览:133
娜拉美妆app怎么使用 浏览:760
有了源码要买服务器吗 浏览:365
app怎么查看自己的存款利息 浏览:515
碧蓝安卓与b站有什么区别 浏览:342
php静态块 浏览:719
ftpmget命令 浏览:475
源码时代怎样 浏览:415
编译aptget 浏览:102
打开防火墙的命令 浏览:161
c混淆编译如何序列化 浏览:808