java 线程

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方法内部的线程)执行完该方法后,别的线程才能进入. 

Java代码  收藏代码
  1. public synchronized void synMethod() {  
  2.         //方法体  
  3.  }  


2 对某一代码块使用synchronized后跟括号,括号里是变量,一次只有一个线程进入该代码块 

Java代码  收藏代码
  1. public int synMethod(int a1){  
  2.         synchronized(a1) {  
  3.           //一次只能有一个线程进入  
  4.         }  
  5. }  


3 synchronized后面括号里是一对象,此时,线程获得的是对象锁 

Java代码  收藏代码
  1. public class MyThread implements Runnable {  
  2.   
  3.        public static void main(String args[]) {  
  4.                 MyThread mt = new MyThread();  
  5.                 Thread t1 = new Thread(mt, "t1");  
  6.                 Thread t2 = new Thread(mt, "t2");                 
  7.                 t1.start();  
  8.                 t2.start();                
  9.         }  
  10.   
  11.        public void run() {  
  12.                 synchronized (this) {  
  13.                   System.out.println(Thread.currentThread().getName());  
  14.               }  
  15.        }  
  16.  }   


4 synchronized后面括号里是类,只要线程进入,则该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁 

Java代码  收藏代码
  1. synchronized(A.class) {  
  2.   //  
  3. }  


示例如下: 

Java代码  收藏代码
  1. public class MyRunnable implements Runnable {  
  2.   
  3.     @SuppressWarnings("deprecation")  
  4.     @Override  
  5.     public void run() {       
  6.         System.out.println("咫尺天涯的第一个线程(Runnable)启动了。。。");  
  7.         synchronized (this) {  
  8.             System.out.println("开始执行任务了...");  
  9.             //模仿一个任务所要的时间  
  10.             try {  
  11.                 Thread.sleep(3000);  
  12.             } catch (InterruptedException e) {  
  13.                 e.printStackTrace();  
  14.             }  
  15.             System.out.println("任务完成了,我来叫醒你好吗?");  
  16.             //推荐使用这种方式来唤醒线程上等待的对象  
  17.             notifyAll();              
  18.         }  
  19.     }  
  20. }  

 

Java代码  收藏代码
  1. public class Main {  
  2.       
  3.     public static void main(String[] args) {  
  4.           
  5.         MyRunnable myRunnable = new MyRunnable();         
  6.         Thread runnable = new Thread(myRunnable,"咫尺天涯(Runnable)");  
  7.         runnable.start();  
  8.           
  9.         synchronized (runnable) {  
  10.               
  11.             try {  
  12.                 System.out.println("快点完成任务呀,等待你来唤醒我。。。");  
  13.                 //当前线程A等待  
  14.                 runnable.wait();  
  15.             } catch (InterruptedException e) {  
  16.                 e.printStackTrace();  
  17.             }    
  18.               
  19.             System.out.println("你叫醒我了...");   
  20.        }          
  21.     }  
  22. }  


输出结果如下: 

Log代码  收藏代码
  1. 快点完成任务呀,等待你来唤醒我。。。  
  2. 咫尺天涯的第一个线程(Runnable)启动了。。。  
  3. 开始执行任务了...  
  4. 任务完成了,我来叫醒你好吗?  
  5. 你叫醒我了...  


网上有个示例不错,它是等待一个计算结果,如下: 

Java代码  收藏代码
  1. /** 
  2. * 计算1+2+3 ... +100的和 
  3. * 
  4. * @author leizhimin 2008-9-15 13:20:49 
  5. */  
  6. public class ThreadB extends Thread {  
  7.     int total;  
  8.   
  9.     public void run() {  
  10.         synchronized (this) {  
  11.             for (int i = 0; i < 101; i++) {  
  12.                 total += i;  
  13.             }  
  14.             //(完成计算了)唤醒在此对象监视器上等待的单个线程,在本例中线程A被唤醒  
  15.             notify();  
  16.         }  
  17.     }  
  18. }  

 

Java代码  收藏代码
    1. /** 
    2. * 计算输出其他线程锁计算的数据 
    3. * 
    4. * @author leizhimin 2008-9-15 13:20:38 
    5. */  
    6. public class ThreadA {  
    7.     public static void main(String[] args) {  
    8.         ThreadB b = new ThreadB();  
    9.         //启动计算线程  
    10.         b.start();  
    11.         //线程A拥有b对象上的锁。线程为了调用wait()或notify()方法,该线程必须是那个对象锁的拥有者  
    12.         synchronized (b) {  
    13.             try {  
    14.                 System.out.println("等待对象b完成计算。。。");  
    15.                 //当前线程A等待  
    16.                 b.wait();  
    17.             } catch (InterruptedException e) {  
    18.                 e.printStackTrace();  
    19.             }  
    20.             System.out.println("b对象计算的总和是:" + b.total);  
    21.         }  
    22.     }  
posted @ 2014-01-19 11:47  火腿骑士  阅读(159)  评论(0编辑  收藏  举报