java——多线程——单例模式的static方法和非static方法是否是线程安全的?

  单例模式的static方法和非static方法是否是线程安全的?

  答案是:单例模式的static方法和非static方法是否是线程安全的,与单例模式无关。也就说,如果static方法或者非static方法不是线程安全的,那么不会因为这个类使用了单例模式,而变的安全。

  闲话休说,看代码:
  

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestSingleton {
    public static void main(String[] args) throws Exception {
        ExecutorService pool = Executors.newFixedThreadPool(10);
        for (int j = 0; j < 100000; j++) {
            pool.submit(new Thread() {
                public void run() {

                    Singleton.get().add();
                }
            });
        }
        pool.shutdownNow();
        while (!pool.isTerminated())
            ;
        System.out.println(Singleton.get().getcnt());
    }
}

class Singleton {
    private static Singleton singleton = new Singleton();

    int cnt = 0;

    private Singleton() {}

    public static Singleton get() {
        return singleton;
    }

    public void add() {
        cnt++;
    }

    public int getcnt() {
        return cnt;
    }
}

  上面的运行结果,一般是不会等于100000的,及运行次数。

  相关笔记:

  The heap is where all the objects live and the stacks are where the threads do their work. Each thread has its own stack and can‘t access each others stacks. Each thread also has a pointer into the code which points to the bit of code they‘re currently running. 

  When a thread starts running a new method it saves the arguments and local variables in that method on its own stack. Some of these values might be pointers to objects on the heap. If two threads are running the same method at the same time they will both have their code pointers pointing at that method and have their own copies of arguments and local variables on their stacks. They will only interfere with each other if the things on their stacks point to the same objects on the heap. In which case all sorts of things might happen.
Strings are immutable (cannot be changed) so we‘re safe if this is the only object being "shared".

  So many threads can be running the same method. They might not be running at the same time - it depends how many cores you have on your machine as the JVM maps Java threads to OS threads, which are scheduled onto hardware threads. You therefore have little control over the way these threads interleave without using complex synchronisation mechanisms.

  threads have their own stack so any method argument and local variable will be unique for each thread.

  

  参考链接:

  http://stackoverflow.com/questions/17343157/static-method-behavior-in-multi-threaded-environment-in-java

  

时间: 2024-12-28 16:27:41

java——多线程——单例模式的static方法和非static方法是否是线程安全的?的相关文章

synchronized 修饰在 static方法和非static方法的区别

Java中synchronized用在静态方法和非静态方法上面的区别 在Java中,synchronized是用来表示同步的,我们可以synchronized来修饰一个方法.也可以synchronized来修饰方法里面的一个语句块.那么,在static方法和非static方法前面加synchronized到底有什么不同呢?大家都知道,static的方法属于类方法,它属于这个Class(注意:这里的Class不是指Class的某个具体对象),那么static获取到的锁,是属于类的锁.而非stati

static方法和非static方法的区别

●生命周期(Lifecycle):静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装载到内存(Memory),不自动进行销毁,会一直存在于内存中,直到JVM关闭.非静态方法(Non-Static Method)又叫实例化方法,属于实例对象,实例化后才会分配内存,必须通过类的实例来引用.不会常驻内存,当实例对象被JVM 回收之后,也跟着消失. ● 在内存中存储位置静态方法和静态变量创建后始终使用同一块内存,是连续的.非静态方法会存在于内存的多个地方,是离散的.

【Java学习笔记】static方法和非static方法的区别

static表示“全局”或者“静态”的意思,用来修饰成员变量和成员方法.被static修饰的成员变量和成员方法独立于该类的任何对象.也就是说,它不依赖类特定的实例,被类的所有实例共享.静态方法可以直接通过类名调用,任何的实例也都可以调用.因此静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法. 因此以下代码中,func_static方法只能访问num2成员,而func方法可以同

java static成员变量方法和非static成员变量方法的区别

这里的普通方法和成员变量是指,非静态方法和非静态成员变量首先static是静态的意思,是修饰符,可以被用来修饰变量或者方法. static成员变量有全局变量的作用       非static成员变量则没有全局变量的作用        局部变量是类的方法里面的变量静态static成员变量是指类的成员变量,他不属于类的对象,只单独属于类,被所有对象共享.当在类中改变他的值时,他在每个对象里面的值都会随之改变. 这也就是说在对象中不能改变他的值,只能在他所在的类中改变,如果他带有final的话(sta

Html.Partial方法和Html.RenderPartial方法

分布视图 PartialView 一般是功能相对独立的,类似用户控件的视图代码片段,可以被多个视图引用,引用方式如下. 1,Html.Partial方法和Html.RenderPartial方法 静态类System.Web.Mvc.Html.PartialExtensions,利用扩展方法,扩展了System.Web.Mvc.HtmlHelper,因此有了Html.Partial方法,方法返回值为MvcHtmlString 静态类System.Web.Mvc.Html.RenderPartial

Server.Transfer方法,Server.Execute方法和Response.Redirect方法有什么异同

(1)Server.Transfer方法: Server.Transfer("m2.aspx");//页面转向(服务器上执行). 服务器停止解析本页,保存此页转向前的数据后,再使页面转向到m2.aspx, 并将转向前数据加上m2.aspx页结果返回给浏览器,注意的是浏览器的地址没发生变化还是m1.aspx, (2)Server.Execute方法: Server.Execute("m2.aspx"); 服务器保存此页转向前的数据后,使页面转向到m2.aspx执行, 

jQuery hover()方法和jQuery toggle()方法用法示例

jQuery hover()方法和jQuery toggle()方法是两个合成事件,类似ready()方法,都属于jQuery自定义的方法.下面来讲解这两个方法的属性和如何使用. 一.hover()方法:语法结构为: hover(enter,leave).用于模拟光标悬停事件.当光标移动到目标元素上时,会触发指定第1个函数(enter);当移出这个元素时,会触发第2个函数(leave). 下面是一段示例代码: $(function(){ $("#panel h5.head").hove

Java多线程系列--“JUC锁”05之 非公平锁

获取非公平锁(基于JDK1.7.0_40) 非公平锁和公平锁在获取锁的方法上,流程是一样的:它们的区别主要表现在"尝试获取锁的机制不同".简单点说,"公平锁"在每次尝试获取锁时,都是采用公平策略(根据等待队列依次排序等待):而"非公平锁"在每次尝试获取锁时,都是采用的非公平策略(无视等待队列,直接尝试获取锁,如果锁是空闲的,即可获取状态,则获取锁).在前面的"Java多线程系列--"JUC锁"03之 公平锁(一)&q

java为什么要重写hashCode方法和equals方法?

之前发布过一篇文章说的是关于 equals方法重写 http://www.cnblogs.com/aL0n4k/p/4777333.html 下面就hashCode方法发表一下本人的理解,仅供参考,交流. 在 关于java重写equals方法 已经提及说,比较2个对象的时候,要比较他们各自的属性. 那么重写hashCode方法是因为我们在接触到集合的时候,里面有个Set接口,他只能添加无序以及不重复的对象元素. 那有人会问,既然是这样我们直接用equals判断不就完了么? 实际上对Set集合而言