论坛首页 Java企业应用论坛

这种静态方法有线程安全问题吗?

浏览 12463 次
精华帖 (0) :: 良好帖 (2) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-07-03  
以前做程序不太考虑线程问题,最近看了一些关于线程讨论的书,不免有些草木皆兵的感觉。思考了一些问题,贴出来,希望大家给予印证。错了还请大家狠批,指点迷津,先谢了。
关于线程安全问题,经过学习,得出的结论是:是因为共享资源引起的。解决线程安全问题,就是解决资源同步的问题。

如果不存在资源共享的问题,是不是就不存在线程安全问题了呢?
比如下面的一个静态方法:
   public static calMonthSum(int one ,double two,……);{
           double sum=0;
            ……
   }

如果说这个静态方法中使用的都是传入的参数和局部变量,调用此方法的对象之间不存在信息交换,那么就不存在线程安全问题。不知下面的测试代码能不能说明这个问题,暂没有报异常。
public class ThreadClass extends Thread {
    private String threadName = "";
    private int sum;
    private int per;
    
    public ThreadClass(int sum,int per); {
        this.sum=sum;
        this.per=per;
        this.setDaemon(true);;
    }

    public void run(); {
        while (true); {
            threadName = Thread.currentThread();.getName();;
            int result=UtilTest.calNumSum(sum,per);;
            System.out.println();;
            
            if(result!=sum*10000); {
                System.out.println(result+"  "+sum*10000);;
                throw new RuntimeException();;
            }//如果发生线程中数据错乱,就不会相等,就报出异常

            System.out.println();; 
        }
    }
}


public class UtilTest {
    public static int calNumSum(int sum, int per); {
        int testSum=sum*10000;
        while(sum!=testSum); {
            sum+=per;
        }
        return sum;
    }
}


public class Test {

    public static void main(String[] args); {
        ThreadClass tc1=new ThreadClass(1,1);;
        tc1.start();;
        ThreadClass tc2=new ThreadClass(1,2);;
        tc2.start();;
        ThreadClass tc3=new ThreadClass(1,4);;
        tc3.start();;
        ThreadClass tc4=new ThreadClass(1,5);;
        tc4.start();;
      }
        while(true);;
    }
}


结论是没有出异常,是不是就说明,这咱静态方法不存在线程安全问题呢?

我又想,如果不存在。是不是可以这么想:每个对象在调用这种静态方法时,在JVM中为它开辟了单独的运行空间,又没有其他外界的信息交流,所以不会有线程安全问题。

思绪有些乱,请大家原谅!
   发表时间:2005-07-03  
安全的,状态保存在栈中
0 请登录后投票
   发表时间:2005-07-03  
1.静态方法如果会更改静态的成员变量,为了线程安全,同样需要同步,只不过这时获得的不是对象实例的锁,而是该类的class对象的锁,例如
public class Foo {
	private static Queue queue = new Queue();;
	public static Object method(Object obj); {
		...
		//访问静态成员变量queue
	}
}

如果会有多个线程同时访问method,需要这样同步:
synchronized(Foo.class); {
	Foo.method(obj);;
}

2.如果实例方法不会更改对象的状态,静态方法不更改静态的成员变量,那么方法就是可重入方法,也就是线程安全的。
0 请登录后投票
   发表时间:2005-07-03  
引用
关于线程安全问题,经过学习,得出的结论是:是因为共享资源引起的。解决线程安全问题,就是解决资源同步的问题

只关心(资源)状态,不关心(指令)执行序列。
0 请登录后投票
   发表时间:2005-07-05  
这个方法不访问共享资源也不改变对象的状态,没关系
0 请登录后投票
   发表时间:2005-07-08  
以Class为锁不是一个好的办法。因为获取Class的过程是低效的。而且,这样会造成有些不需要同步的方法也不能访问Class.
0 请登录后投票
   发表时间:2005-07-25  
yk 写道
这个方法不访问共享资源也不改变对象的状态,没关系

恩,只是全局方法,没访问全局变量,因而是安全的.
0 请登录后投票
   发表时间:2005-07-25  
推荐看看这个:

Java虚拟机的深入研究

http://gceclub.sun.com.cn/staticcontent/html/2004-04-09/jvm.html
0 请登录后投票
   发表时间:2005-09-05  
如果该静态变量是ThreadLocal型的,想改变他的值时要同步么?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics