`

Integer不能作为synchronized的对象吗

 
阅读更多

 

public class SychronizedTest implements Runnable {
	
	private Timer t = new Timer();

	public static void main(String[] args) {
		
		SychronizedTest st = new SychronizedTest();

		Thread thread1 = new Thread(st, "Thread1");
		Thread thread2 = new Thread(st, "Thread2");

		thread1.start();
		thread2.start();
	}

	public void run() {
		this.t.add();
	}
}

class Timer {
	private Integer i = 0;
	
	private Object o = new Object();

	public void add() {
		//i 没有被2个线程竞争,2个线程都可以获得对i的锁,但是如果换成o,则一个线程等待一个线程阻塞
		//synchronized (o) {
		synchronized (i) {
			this.i++;
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("您是第" + this.i + "个使用i的线程," + Thread.currentThread().getName());

		}
	}
}

 //i 没有被2个线程竞争,2个线程都可以获得对i的锁,但是如果换成o,则一个线程等待一个线程阻塞

 

有点奇怪,换成atmoicinteger也是可以的,观察线程栈也可以说明这一点

 

"Thread2" prio=6 tid=0x17122400 nid=0x1d18 at breakpoint[0x172df000]
   java.lang.Thread.State: RUNNABLE
	at com.google.prophet.quickstart.basic.thread.Timer.add(SychronizedTest.java:34)
	- locked <0x02fb05c8> (a java.lang.Integer)
	at com.google.prophet.quickstart.basic.thread.SychronizedTest.run(SychronizedTest.java:19)
	at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
	- None

"Thread1" prio=6 tid=0x17121800 nid=0x18b8 at breakpoint[0x1728f000]
   java.lang.Thread.State: RUNNABLE
	at com.google.prophet.quickstart.basic.thread.Timer.add(SychronizedTest.java:34)
	- locked <0x02fb05f8> (a java.lang.Integer)
	at com.google.prophet.quickstart.basic.thread.SychronizedTest.run(SychronizedTest.java:19)
	at java.lang.Thread.run(Thread.java:662)

   Locked ownable synchronizers:
	- None
 

 

0x02fb05f8
0x02fb05c8

  Integer是一个对象但是id却不同,可能这个Integer各自在2个线程的工作内存中,而不是共享内存中,目前我只能这么解释,而Object,或者是AtomicInteger则是创建在了共享内存中,所以可以进行同步。

 

分享到:
评论

相关推荐

    Java线程及同步(synchronized)样例代码

    - **同步锁的选择**:使用了一个名为`threadCounterLock`的静态变量作为锁对象,确保每次只有一个线程能进入`synchronized`代码块。 - **循环和休眠处理**:在`run`方法中,线程会持续运行直到达到预设的时间点(30...

    关于Java自动装箱(autoboxing)的一些意想不到的结果

    4. 不应使用自动装箱的对象作为锁:不应使用自动装箱后的数字对象或字符串对象作为synchronized代码块的锁对象。由于自动装箱和缓存的特性,可能会导致锁行为与预期不同,例如,两个看似不同的包装类对象可能引用同...

    超级有影响力霸气的Java面试题大全文档

     声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,...

    关于synchronized有趣的同步问题

    解决这个问题的一种方法是将`count`声明为volatile,这将确保所有线程都能看到`count`的最新值,但volatile并不保证原子性,因此仍然不能解决自增操作的并发问题。正确的做法是将`synchronized`作用于包含自增操作的...

    Java基础面试重点.pdf

    - String是不可变对象,一旦创建,其值不能改变。 - StringBuffer是可变的,修改时不会创建新对象,效率较高。 - String是final类,不能被继承,而StringBuffer可以扩展。 9. **同步(Synchronized)**: - ...

    【05-面向对象(下)】

    •但对引用类型的变量而言,它仅仅保存的是一个引用,final只能保证他的地址不变,但不能保证对象,所以引用 类型完全可以改变他的对象。 可执行“宏替换”的final变量 •对一个final变量来说,不管它...

    JAVA面试宝典2013版

    13. 在static方法内部不能直接调用非static方法,因为非static方法依赖于对象实例,而static方法属于类,不依赖于任何对象实例。 14. Integer是int的封装类,int是基本数据类型。Integer可以为null,而int不能。 ...

    java题库perfect

    也不能直接调用其他类的实例方法,除非通过对象引用。 3. **Java 编译器 javac**:javac 可以同时编译多个源文件,并可以指定编译结果的输出目录,但环境变量如 class path 通常在运行时设置,不是在编译时指定,...

    CoreJava_面试题

    13. Integer是int的包装类,它们之间的主要区别在于 Integer 是对象类型,可以为null,而 int 是基本数据类型,不能为null。 14. Math.round(11.5)的结果是12,Math.round(-11.5)的结果是-11,因为round方法对于.5...

    Java面试题一站式全收录

    * final:用来修饰类、变量或方法,表明该类不能被继承,该变量或方法不能被修改。 * finally:用来处理异常,一定会被执行的语句块,经常被用在需要释放资源的情况下。 * finalize():是一种特殊的方法,用于在对象...

    java面试2013

    而如果变量是对象,那么整个对象不能被重新赋值。 11. `==`比较的是两个对象的引用是否相同,而`equals()`方法比较的是两个对象的内容是否相等。 12. 静态变量属于类,所有类的实例共享;实例变量属于每个实例对象...

    spotify java面试题库.docx

    如果对象是不可变的(如String),则对象本身也不能改变。 9. ==比较的是对象的引用,而equals方法比较的是对象的内容。基本类型的比较不受此影响,因为它们直接比较数值。 10. 静态变量属于类,实例变量属于对象...

    java面试宝典

    25. `abstract`方法不能同时是`static`、`native`和`synchronized`,因为这些修饰符的语义与抽象方法不符。 26. 内部类是定义在另一个类内部的类,`Static Nested Class`是静态内部类,可以直接通过外部类名访问;`...

    前端js基础学习实践,面试重点

    - 不建议使用基本数据类型的对象(如`String`、`Integer`、`Long`等)作为锁的对象,因为这些类型的值变化会导致锁的对象发生变化,从而使锁失去作用。 3. **`synchronized`的优化**: - **JDK 1.6的优化**:在JDK ...

    Java软件工程师面试宝典

    10. final关键字修饰变量时,引用本身不可变还是引用的对象不可变? final关键字修饰变量时,引用本身不可变,即变量的引用地址不能改变。如果变量是引用类型,则引用的对象可以改变,但引用本身不可变。 11. “==...

    spotify java面试题库.pdf

    51. 当一个线程进入synchronized方法A后,其他线程不能进入该对象的另一个synchronized方法B,因为锁是互斥的。 52. 线程的五种状态:新建、就绪、运行、阻塞和终止。 53. 创建线程的两种方式:继承Thread类并重写...

    java程序员面试宝典

    52. 当线程进入一个对象的synchronized方法时,其他线程不能进入同一个对象的synchronized方法,但可以进入同一个对象的其他非synchronized方法。 由于篇幅限制,以上知识点仅为部分摘录,具体内容需要结合实际文档...

    java华为面试题目

    它是一个不可变的字符序列,这意味着一旦创建就不能修改。 3. **int与Integer的区别**:int是Java的基本数据类型,而Integer是它的包装类。int是值类型,直接存储在栈中,而Integer是对象,存储在堆中。此外,...

    Java面试宝典2013最新版.doc

    - 如果一个线程已经进入了一个对象的`synchronized`方法,其他线程不能进入该对象的其他`synchronized`方法。 #### 53. 线程的状态 - **新建(New)**:新创建了一个线程对象。 - **就绪(Runnable)**:线程对象创建后...

Global site tag (gtag.js) - Google Analytics