多线程下synchronized修饰static方法与非static方法的区别

一直对多线程的概念比较模糊,今天就写了个关于变量原子操作的小程序,好让自己加深一下理解

代码如下:

 
  1. package atomic;

  2.  
  3. public class JoinThread extends Thread {

  4.  
  5. public static int i = 0;

  6.  
  7. //public static AtomicInteger atomicInteger = new AtomicInteger(0);

  8.  
  9. public synchronized void inc(){

  10. i ++;

  11. }

  12. @Override

  13. public void run() {

  14. for (int x = 0; x < 10; x++) {

  15. inc();

  16. try {

  17. Thread.sleep(33);

  18. } catch (InterruptedException e) {

  19. e.printStackTrace();

  20. }

  21. }

  22. }

  23.  
  24. public static void main(String[] args) throws InterruptedException {

  25. // TODO Auto-generated method stub

  26. // JoinThread jt = new JoinThread();

  27. Thread[] t = new Thread[100];

  28. for (int i = 0; i < t.length; i++) {

  29. t[i] = new JoinThread();

  30. }

  31. for (int i = 0; i < t.length; i++) {

  32. t[i].start();

  33. }

  34. for (int i = 0; i < t.length; i++) {

  35. t[i].join();

  36. }

  37. System.out.println(JoinThread.i);

  38. }

  39.  
  40. }


执行完发现,i并没有如想像中的输出1000,即使i添加volatile进行修饰,也不会输出1000,值是随机变化的。

将inc()方法添加static修饰,结果无问题,准确无误的输出1000。

另外一种改法,将代码改成:

 
  1. Thread[] t = new Thread[100];

  2. for (int i = 0; i < t.length; i++) {

  3. t[i] = new JoinThread();

  4. }

修改成:

 
  1. JoinThread jt = new JoinThread();

  2. Thread[] t = new Thread[100];

  3. for (int i = 0; i < t.length; i++) {

  4. t[i] = new Thread(jt);

  5. }

结果无问题,准确无误的输出1000

这里主要涉及到类对象(static方法),对象方法(非static方法)

我们知道,当synchronized修饰一个static方法时,多线程下,获取的是类锁(即Class本身,注意:不是实例);

当synchronized修饰一个非static方法时,多线程下,获取的是对象锁(即类的实例对象)

所以,当synchronized修饰一个static方法时,创建线程不管是new JoinThread()还是new Thread(new JoinThread()),在run方法中执行inc()方法都是同步的;

相反,当synchronized修饰一个非static方法时,如果用new JoinThread()还是new Thread(new JoinThread())方式创建线程,就无法保证同步操作,因为这时

inc()是属于对象方法,每个线程都执有一个独立的对象实例new JoinThread(),所以多线程下执行inc()方法并不会产生互斥,也不会有同步操作。

另外如果考虑到变更的原子操作,可使用atomic包下面的包装对象,这些对象都是对volatile修饰变量的一种延伸,可保证变量的原子操作而不用去同步方法或

代码块是否同步。

猜你喜欢

转载自blog.csdn.net/u010112268/article/details/82745328
今日推荐