多线程下synchronized修饰static方法与非static方法的区别
2013-08-21 18:06
465 查看
一直对多线程的概念比较模糊,今天就写了个关于变量原子操作的小程序,好让自己加深一下理解
代码如下:
执行完发现,i并没有如想像中的输出1000,即使i添加volatile进行修饰,也不会输出1000,值是随机变化的。
将inc()方法添加static修饰,结果无问题,准确无误的输出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修饰变量的一种延伸,可保证变量的原子操作而不用去同步方法或
代码块是否同步。
代码如下:
package atomic; public class JoinThread extends Thread { public static int i = 0; //public static AtomicInteger atomicInteger = new AtomicInteger(0); public synchronized void inc(){ i ++; } @Override public void run() { for (int x = 0; x < 10; x++) { inc(); try { Thread.sleep(33); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub // JoinThread jt = new JoinThread(); Thread[] t = new Thread[100]; for (int i = 0; i < t.length; i++) { t[i] = new JoinThread(); } for (int i = 0; i < t.length; i++) { t[i].start(); } for (int i = 0; i < t.length; i++) { t[i].join(); } System.out.println(JoinThread.i); } }
执行完发现,i并没有如想像中的输出1000,即使i添加volatile进行修饰,也不会输出1000,值是随机变化的。
将inc()方法添加static修饰,结果无问题,准确无误的输出1000。
另外一种改法,将代码改成:
Thread[] t = new Thread[100]; for (int i = 0; i < t.length; i++) { t[i] = new JoinThread(); }修改成:
JoinThread jt = new JoinThread(); Thread[] t = new Thread[100]; for (int i = 0; i < t.length; i++) { t[i] = new Thread(jt); }结果无问题,准确无误的输出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修饰变量的一种延伸,可保证变量的原子操作而不用去同步方法或
代码块是否同步。
相关文章推荐
- 多线程下synchronized修饰static方法与非static方法的区别
- 多线程下synchronized修饰static方法与非static方法的区别
- java多线程下synchronized修饰static方法与非static方法的区别
- synchronized 修饰在 static方法和非static方法的区别
- synchronized 修饰在 static方法和非static方法的区别
- Java多线程之Synchronized应用在static和非static方法上的区别
- Java语言中synchronized 修饰在 static方法和 非static方法的区别
- Java中synchronized 修饰在static方法和非static方法的区别
- synchronized 修饰在 static方法和非static方法的区别
- 多线程synchronized和synchronized static方法的区别
- synchronized修饰static方法与非static方法的区别
- Java语言中synchronized 修饰在 static方法和 非static方法的区别
- synchronized修饰非static方法与修饰static方法的区别
- Java中synchronized 修饰在 static方法和 非static方法的区别
- synchronized 修饰在 static方法和 非static方法的区别
- 多线程:synchronized同步方法和同步代码快的区别
- Java多线程程序中synchronized修饰方法的使用实例
- Java - 抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?
- 【java】synchronized修饰静态方法和非静态方法的区别
- Java 多线程:synchronized 关键字 3ff0 用法(修饰类,方法,静态方法,代码块)