请问哪位大神能解释一下,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 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呢?
应该是你这个方法的原因吧,它是静态方法,线程锁的是Counter 的CLASS对象,而不是Counter 的对象。
你循环1000次 就是调用Counter 的CLASS对象的inc方法1000次。
来看最后结果的,这句话不一定是在最后执行的。
{
//首先你以前来锁这个对象是错的 他是会变的
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你参考下这是我按照你代码改的加的批准
得不到正确结果的原因是:你能保证你执行System.out.println("运行结果:Counter.count=" + Counter.count);这条命令的时候,你那1000个线程都执行结束了吗?
你可以在启动那1000个线程后让主线程睡上一会,你就可以得到正确结果了
/**
* The value of the <code>Integer</code>.
*
* @serial
*/
private final int value;
之前还真不知道原来它的value是不可改变的!!!那Integer效率看来不行啊。
synchronized(Counter.class){
count++;
System.out.println(count);
}count是属于Counter 的CLASS的,而不是属于每个Counter对象。