http://liuzidong.iteye.com/blog/1188706
Java多线程入门大全(适用于有一定基础者)
http://www.chinaitpower.com/A/2002-04-09/19260.html
Java多线程sleep(),join(),interrupt(),wait(),notify()
http://www.blogjava.net/fhtdy2004/archive/2009/06/08/280728.html
JAVA多线程suspend()、resume()和wait()、notify()的区别
http://luckyapple.iteye.com/blog/457298
总结如下:
1.有synchronized的地方不一定有wait,notify,notifyAll,
2.有wait,notify的地方必有synchronized.这是因为wait和notify不是属于线程类,而是每一个对象都具有的方法,而且,这两个方法都和对象锁有关,有锁的地方,必有synchronized.
3.如果要把notify和wait方法放在一起用的话,必须先调用notify后调用wait,因为如果调用完wait,该线程就已经不是current thread了.
4 推荐使用notifyAll.
一 synchronized的4种用法
1 方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入.
- public synchronized void synMethod() {
-
- }
2 对某一代码块使用synchronized后跟括号,括号里是变量,一次只有一个线程进入该代码块
- public int synMethod(int a1){
- synchronized(a1) {
-
- }
- }
3 synchronized后面括号里是一对象,此时,线程获得的是对象锁
- public class MyThread implements Runnable {
-
- public static void main(String args[]) {
- MyThread mt = new MyThread();
- Thread t1 = new Thread(mt, "t1");
- Thread t2 = new Thread(mt, "t2");
- t1.start();
- t2.start();
- }
-
- public void run() {
- synchronized (this) {
- System.out.println(Thread.currentThread().getName());
- }
- }
- }
4 synchronized后面括号里是类,只要线程进入,则该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁
- synchronized(A.class) {
-
- }
示例如下:
- public class MyRunnable implements Runnable {
-
- @SuppressWarnings("deprecation")
- @Override
- public void run() {
- System.out.println("咫尺天涯的第一个线程(Runnable)启动了。。。");
- synchronized (this) {
- System.out.println("开始执行任务了...");
-
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("任务完成了,我来叫醒你好吗?");
-
- notifyAll();
- }
- }
- }
- public class Main {
-
- public static void main(String[] args) {
-
- MyRunnable myRunnable = new MyRunnable();
- Thread runnable = new Thread(myRunnable,"咫尺天涯(Runnable)");
- runnable.start();
-
- synchronized (runnable) {
-
- try {
- System.out.println("快点完成任务呀,等待你来唤醒我。。。");
-
- runnable.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- System.out.println("你叫醒我了...");
- }
- }
- }
输出结果如下:
- 快点完成任务呀,等待你来唤醒我。。。
- 咫尺天涯的第一个线程(Runnable)启动了。。。
- 开始执行任务了...
- 任务完成了,我来叫醒你好吗?
- 你叫醒我了...
网上有个示例不错,它是等待一个计算结果,如下:
-
-
-
-
-
- public class ThreadB extends Thread {
- int total;
-
- public void run() {
- synchronized (this) {
- for (int i = 0; i < 101; i++) {
- total += i;
- }
-
- notify();
- }
- }
- }
-
-
-
-
-
- public class ThreadA {
- public static void main(String[] args) {
- ThreadB b = new ThreadB();
-
- b.start();
-
- synchronized (b) {
- try {
- System.out.println("等待对象b完成计算。。。");
-
- b.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("b对象计算的总和是:" + b.total);
- }
- }
- }