单例在多线程中存在同步问题,但是对那些变量有影响呢?原因? 以下纯属个人观点,不吝赐教:
先上代码:
Test类代码
- public class Test extends Thread {
- public void run() {
- Singleton.getInstance().print(this.getName());
- }
- public static void main(String[] args) {
- Test test1= new Test ();
- Test test2= new Test ();
- test1.setName("T1");
- test2.setName("T2");
- test1.start();
- test2.start();
- }
- }
public class Test extends Thread { public void run() { Singleton.getInstance().print(this.getName()); } public static void main(String[] args) { Test test1= new Test (); Test test2= new Test (); test1.setName("T1"); test2.setName("T2"); test1.start(); test2.start(); } }
单例1代码
- public class Singleton {
- private static Singleton instance = new Singleton();
- public static Singleton getInstance() {
- return instance;
- }
- int a = 0;
- public void print(String str){
- for (; a < 20; a++) {
- System.out.println("["+str+"]执行" + a);
- try {
- if(a==10 && str.equals("T2")){
- a = 0;
- }
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
public class Singleton { private static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } int a = 0; public void print(String str){ for (; a < 20; a++) { System.out.println("["+str+"]执行" + a); try { if(a==10 && str.equals("T2")){ a = 0; } Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } 这个时候 当T2线程改变a的值,T1线程a的值也改变了。原理大家都知道。
在看下面的代码:
Java代码
public
class Singleton {- private
static Singleton instance = new Singleton(); - public
static Singleton getInstance() { - return instance;
- }
- public
void print(String str){ - for (int a = 0; a < 20; a++) {
- System.out.println("["+str+"]执行" + a);
- try {
- if(a==10 && str.equals("T2")){
- a = 0;
- }
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
public class Singleton { private static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } public void print(String str){ for (int a = 0; a < 20; a++) { System.out.println("["+str+"]执行" + a); try { if(a==10 && str.equals("T2")){ a = 0; } Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } 这个时候 当T2线程改变a的值,T1线程a的值并没有改变。
原因:
成员变量存储在堆中的对象里面,由垃圾回收器负责回收。
局部变量存储在栈内,随着方法的消失而消失。
T1和T2并发执行,当T1退出cpu,T2执行的时候,T1方法并没有结束,所以 不会释放该方法相关栈内存。
那么如何区分T1和T2的a呢?
虽然Singleton 是单例,但是在执行的时候,T1的栈信息和T2的栈信息是相互独立的互不影响。
本文转自www.35java.com