请问哪位大神能解释一下,synchronized修饰方法和作为块的区别呢?例如以下代码:
public class Counter {
public static Integer count = 0;
public static void inc() {
//这里延迟1毫秒,使得结果明显
try {
Thread.sleep(30);
} catch (InterruptedException e) {
}
//注意看这里。监控count了。
synchronized(count){
count++;
System.out.println(count);
}
}
public static void main(String[] args) {
//同时启动1000个线程,去进行i++计算,看看实际结果
for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {
@Override
public void run() {
Counter.inc();
}
}).start();
}
//这里每次运行的值都有可能不同,可能为1000
System.out.println("运行结果:Counter.count=" + Counter.count);
}
}
为什么synchronized作为块的时候得出的结果可能不是1000,而如果改为修饰方法inc时结果却可以正确,为1000呢?
------解决方案--------------------------------------------------------
public synchronized static void inc()
应该是你这个方法的原因吧,它是静态方法,线程锁的是Counter 的CLASS对象,而不是Counter 的对象。
你循环1000次 就是调用Counter 的CLASS对象的inc方法1000次。
------解决方案--------------------------------------------------------
synchronized锁定的是实例块,但是你的count是static的对象,并且你的方法也是static的方法,所以你用实例锁去锁class对象根本没用的!!!所以你需要把synchronized放到方法上锁定static方法,也就是锁的class对象了。如果你需要用synchronized块的话,需要把方法改成非静态方法
------解决方案--------------------------------------------------------
package com.djk.thread;
public class Counter
{
//首先你以前来锁这个对象是错的 他是会变的
public static Integer count =0;
//现在我给你重弄一把锁,这把锁是静态的保证只有一个对象是同一把锁
private static Object object = new Object();
//这里要改成非静态的 你也可以再这里加synchronized 效果也是1000,主要线程中都是同一个对象调用这个方法
public void inc()
{
//这里延迟1毫秒,使得结果明显
try
{
Thread.sleep(30);
}
catch (InterruptedException e)
{
}
//这里不要锁count是没用的,锁object 最后执行的结构是1000
synchronized(object)
{
count++;
System.out.println(count);
}
}
public static void main(String[] args)
{
//同时启动1000个线程,去进行i++计算,看看实际结果
//这边这样定义是为了保证线程中时同一个对象调用方法
final Counter c = new Counter();
for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {
@Override
public void run()
{
c.inc();
}
}).start();
}
//这里每次运行的值都有可能不同,可能为1000
//还有这里是没必要写的,看这个是看不出结果的,这句话是主线程的,主线程不一定是在最后执行,可能在你生成线程的时候就执行了
System.out.println("运行结果:Counter.count=" + Counter.count);
}
}
lz你参考下这是我按照你代码改的加的批准