java的synchronized关键字,多线程编程的注意事项

学习多线程编程的时候,有这么段程序,不管如何输入结果总是不能够锁住变量n,

 

public class JoinThread extends Thread {
      private static int n = 0;
    // private static Object obj=new Object();
    public void run() {
        for (int i = 0; i < 10; i++)
            try {
                addN();
                sleep(3); // 为了使运行结果更随机,延迟3毫秒
            } catch (Exception e) {
            }
    }

    private synchronized   void addN() {
            n++;
    }

    public void printn() {
        System.out.println("n=" + n);
    }

    public static void main(String[] args) throws Exception {
        Thread threads[] = new Thread[100];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new JoinThread();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        // if (args.length > 0) {
        for (int i = 0; i < threads.length; i++) {
            // 100个线程都执行完后继续
            threads[i].join();
        }
        // }
        new JoinThread().printn();
    }

}

 

有时候n=1000,有时候n=998甚至会变成993

 

反复查阅资料才知道是synchronized关键字用法错误。

 

synchronized关键字的作用域有二种:

1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线 程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的 synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;

2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。

 

所以上面程序中的n变量是属于类范围变量,除了用synchronized static 关键字,不管用什么方法都锁不住。

 

所以将上面程序修改为

public class JoinThread extends Thread {
      private static int n = 0;
    // private static Object obj=new Object();
    public void run() {
        for (int i = 0; i < 10; i++)
            try {
                addN();
                sleep(3); // 为了使运行结果更随机,延迟3毫秒
            } catch (Exception e) {
            }
    }

    private synchronized static  void addN() {
            n++;
    }

    public void printn() {
        System.out.println("n=" + n);
    }

    public static void main(String[] args) throws Exception {
        Thread threads[] = new Thread[100];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new JoinThread();
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
        // if (args.length > 0) {
        for (int i = 0; i < threads.length; i++) {
            // 100个线程都执行完后继续
            threads[i].join();
        }
        // }
        new JoinThread().printn();
    }

}

 

则可以看到n=1000的正确结果,n变量被正确锁住了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值