今天写一个测试类,主要是测试wait(long timeout)到底会不会自动notify,到后来发现
一些很诡异的东西。
package com.hp.thread.chapter04; public class WaitAndNotify { private Object obj = new Object(); public static void testPureWait(){ new Thread(new Runnable(){ public void run() { synchronized (this) { try { System.out.println("thread 0"); wait(); System.out.println("thread 0 waited..."); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new Thread(new Runnable(){ public void run() { synchronized (this) { try { System.out.println("thread 1"); wait(1000); System.out.println("thread 1 waited..."); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } public void testWait1000(){ new Thread(new Runnable(){ public void run() { System.out.println("thread 0 " + this); synchronized (obj) { while(true){ try { System.out.println("thread 0 running..."); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); new Thread(new Runnable(){ public void run() { System.out.println("thread 1 " + this); synchronized (obj) { try { while(true){ wait(1000); System.out.println("thread 1 waited..."); } } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } //通过打印出来的this,发现2个是不同的结果,为什么呢? //因为this是指向当前对象的引用,不过方法中都是new Thread(new Runnable(){}).start() //方式来生成,都是通过匿名的方式,所以每次的this都是指向new Thread()的WaitAndNotify对象 public void testWait1000_2(){ new Thread(new Runnable(){ public void run() { synchronized (this) { while(true){ try { System.out.println("thread 0"); System.out.println("thread 0 running..."); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); new Thread(new Runnable(){ public void run() { synchronized (this) { try { while(true){ System.out.println("thread 1"); wait(1000); System.out.println("thread 1 waited..."); } } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } public static void testWait(){ new Thread(new Runnable(){ public void run() { while(true){ synchronized (this) { try { System.out.println("..."); wait(); System.out.println("waited..."); notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); new Thread(new Runnable(){ public void run() { while(true){ synchronized (this) { try { notifyAll(); System.out.println("notify..."); wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); } /** * @param args */ public static void main(String[] args) { // testPureWait(); // testWait(); new WaitAndNotify().testWait1000(); } }
调用testWait1000_2方法得到的结果不是我期望(线程0始终在运行,线程1是不会运行的),但世界的结果恰恰相反,好事2个线程不相干,测试结果如下
thread 0 thread 0 running... thread 1 thread 1 waited... thread 0 thread 0 running... thread 1 thread 0 thread 0 running... thread 1 waited... thread 1
但是运行testWait1000正好是我要的结果,开始百思不得其解,后来打印this发现mystery了
thread 0 com.hp.thread.chapter04.WaitAndNotify$3@525483cd thread 0 running... thread 1 com.hp.thread.chapter04.WaitAndNotify$4@67f1fba0 thread 0 running... thread 0 running... thread 0 running... thread 0 running...
发现2个this的地址完全不一样,细想一下豁然开朗。
相关推荐
- 如果一个线程正在访问对象的`synchronized(this)`同步代码块,其他线程仍然可以访问该对象的非`synchronized(this)`代码块。例如: ```java package ts; public class Thread2 { public void m4t1() { ...
Synchronized 关键字的作用是取得对象的锁,而不是把一段代码或函数当作锁。每个对象只有一个锁与之相关联。实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。 当 ...
在Java编程语言中,`synchronized`关键字是一个重要的并发控制机制,用于确保多线程环境下的数据一致性。本文将深入探讨`synchronized`的几种使用示例,包括方法加锁、代码块加锁(针对`this`和对象)以及静态方法...
Java 中的 synchronized 关键字是用于解决多线程并发问题的重要工具之一。它可以被用于方法、代码块和变量上,以实现对共享资源的互斥访问控制。本文将对 Java 中的 synchronized 用法进行详细的解释和分析。 一、...
当一个线程进入`synchronized`代码块或方法时,其他试图进入同一块的线程将被阻塞,直到持有锁的线程退出。 二、同步单个对象 1. 同步方法:在方法声明前加上`synchronized`关键字,使得每次只有一个线程能执行该...
在Java多线程编程中,`synchronized`关键字是一个至关重要的工具,用于实现线程间的同步,以确保共享资源的安全访问。本实例大全将全面解析`synchronized`的使用方式,包括同步方法、同步语句块、类锁和对象锁。 ##...
在Java编程语言中,`synchronized`是一个非常重要的关键字,它主要用于实现同步控制机制。通过使用`synchronized`,可以确保同一时刻只有一个线程能够访问被标记为同步的方法或代码块,从而避免多线程环境下的数据不...
在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。
以下是一个具体的示例程序,用于演示多个线程访问同一个对象的`synchronized(this)`同步代码块时的行为。 ```java package threads; public class Thread1 implements Runnable { public void run() { ...
当一个线程访问某个对象的一个`synchronized`方法时,它就获得了该对象的锁,并且其他线程无法再访问该对象的其他`synchronized`方法。 - **互斥性**:通过`synchronized`关键字实现的锁具有互斥性,也就是说,一次...
synchronized (this) { count++; } } // 使用自定义锁 private final Object lock = new Object(); public void incrementWithCustomLock() { synchronized (lock) { count++; } } } ``` #### 性能...
Java 锁机制 Synchronized 是 Java 语言中的一种同步机制,用于解决多线程并发访问共享资源时可能出现的一些问题。 Java 锁机制 Synchronized 的概念 在 Java 中,每个对象都可以被看作是一个大房子,其中有多个...
Java中的`synchronized`关键字是多线程编程中的一个重要概念,用于控制并发访问共享资源,以保证数据的一致性和完整性。这个关键词提供了互斥锁机制,防止多个线程同时执行同一段代码,确保了线程安全。 一、`...
在Java编程语言中,`synchronized`关键字是一个非常重要的并发控制机制,用于保证多线程环境下的数据一致性。本文将深入解析`synchronized`的工作原理、使用方式以及它在并发编程中的重要性。通过分析提供的源码,...
通过使用`synchronized`,可以确保同一时间只有一个线程能够执行特定代码块,从而防止数据的不一致性和线程安全问题。下面将详细介绍`synchronized`的用法及其在不同场景下的应用。 1. 同步方法: 当`synchronized...
- **方法同步**:在方法声明前加上`synchronized`关键字,这将使得整个方法成为同步方法,每次只有一个线程可以执行该方法。 ```java public synchronized void someMethod() { // ... } ``` - **代码块...
这意味着在任意时刻,都只有一个线程可以访问该实例的所有`synchronized`方法,或者进入由`synchronized(this)`标记的代码块。对于静态方法,锁对象则是该类的Class对象。 ```java public class MyClass { private...
`synchronized`提供了一种机制,使得在多线程环境中,对特定代码或方法的访问变得有序和安全。 首先,`synchronized`可以应用于两种情况:同步方法和同步代码块。同步方法是通过在方法声明前加上`synchronized`...
在Java编程语言中,`synchronized`关键字是一个非常重要的概念,它用于实现线程同步,以确保多线程环境下的数据一致性与安全性。本示例"java synchronized demo"旨在探讨`synchronized`关键字的用法及其作用机制。...
Java中的`synchronized`关键字是多线程编程中的一个重要概念,用于控制并发访问共享资源时的同步机制。在Java中,当多个线程试图同时访问和修改同一块代码或数据时,可能会导致数据不一致的问题。为了解决这个问题,...