`
ivyljw
  • 浏览: 3938 次
  • 性别: Icon_minigender_2
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

JAVA线程各方法

阅读更多


wait()、notify()、notifyAll()和suspend()、resume()、sleep()的讨论

1 这两组函数的区别

1) wait()使当前线程进入停滞状态时,还会释放当前线程所占有的“锁标志”,从而使线程对象中的synchronized资源可被对象中别的线程使用;而suspend()和sleep()使当前线程进入停滞状态时不会释放当前线程所占有的“锁标志”。

2) 前一组函数必须在synchronized函数或synchronized block中调用,否则在运行时会产生错误;而后一组函数可以non-synchronized函数和synchronized block中调用。

2 这两组函数的取舍

Java2已不建议使用后一组函数。因为在调用wait()时不会释放当前线程所取得的“锁标志”,这样很容易造成“死锁”。

 

 

sleep() 和 wait() 有什么区别? 搞线程的最爱
  sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级 (b)正在运行的线程因为其它原因而阻塞。
wait()是线程交互时,如果线程对一个同步对象(方法)x 发出一个wait()调用,该线程会暂停执行,被调对象(方法)进入等待状态,直到被唤醒或等待时间到。

Wait时别的线程可以访问锁定对象(调用wait,锁就撒手);
调用wait方法的时候必需锁定该对象;
Object提供的方法
Sleep时别的线程也不可以访问锁定对象(睡着也抱着锁);
Thread提供的方法
请参考下面2个例子就全明白了......

 

 

 

同步:
a.每个对象只有一把锁
b.一个线程访问同步方法时候,别的线程可以访问该对象的其他非同步的方法,而且也可以影响同步方法内部的变量。


例1:

Java代码 复制代码
  1. public class TT implements Runnable {   
  2.     int b = 100;   
  3.        
  4.     public synchronized void m1() throws Exception{   
  5.         b = 1000;   
  6.         Thread.sleep(1000);   
  7.         System.out.println("b = " + b);   
  8.     }   
  9.        
  10.     public synchronized void m2() throws Exception {   
  11.         Thread.sleep(3000);   
  12.         b = 2000;   
  13.     }   
  14.        
  15.     public void run() {   
  16.         try {   
  17.             m1();   
  18.         } catch(Exception e) {   
  19.             e.printStackTrace();   
  20.         }   
  21.     }   
  22.        
  23.     public static void main(String[] args) throws Exception {   
  24.         TT tt = new TT();   
  25.         Thread t = new Thread(tt);   
  26.         t.start();   
  27.         tt.m2();   
  28.            
  29.         System.out.println(tt.b);   
  30.     }   
  31. }   
  32.   
  33.   
  34. ===输出结果有2中可能====   
  35. 如果主线程锁定当前对象,输出结果为:   
  36. 2000  
  37. b = 1000  
  38. 如果子线程锁定当前对象,输出结果为:   
  39. 1000  
  40. b = 1000  
public class TT implements Runnable {
	int b = 100;
	
	public synchronized void m1() throws Exception{
		b = 1000;
		Thread.sleep(1000);
		System.out.println("b = " + b);
	}
	
	public synchronized void m2() throws Exception {
		Thread.sleep(3000);
		b = 2000;
	}
	
	public void run() {
		try {
			m1();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) throws Exception {
		TT tt = new TT();
		Thread t = new Thread(tt);
		t.start();
		tt.m2();
		
		System.out.println(tt.b);
	}
}


===输出结果有2中可能====
如果主线程锁定当前对象,输出结果为:
2000
b = 1000
如果子线程锁定当前对象,输出结果为:
1000
b = 1000



例2:范例名称:生产者--消费者问题
  遇到互斥的问题时候如何解决得呢?
  答:将互斥的2个操作放到同一个类的2个方法中,然后让这2个方法都加上synchronized关键字修饰


/* * 源文件名称:SyncTest.java
* 要  点:
* 1. 共享数据的不一致性/临界资源的保护
* 2. Java对象锁的概念
* 3. synchronized关键字/wait()及notify()方法
*/

Java代码 复制代码
  1. package com.wlh;   
  2.   
  3. public class ProduceConsumer {      
  4.     public static void main(String args[]){      
  5.             SyncStack stack = new SyncStack();      
  6.             Runnable p=new Producer(stack);      
  7.             Runnable c = new Consumer(stack);      
  8.             Thread t1 = new Thread(p);      
  9.             Thread t2 = new Thread(c);      
  10.             t1.start();      
  11.             t2.start();      
  12.     }      
  13. }      
  14.      
  15.   /**  
  16.    * 支持多线程同步操作的堆栈的实现   
  17.    * 因为只有一个线程能够锁定当前对象,而同步方法的执行前先锁定当前对象,  
  18.    * 所以同一时刻,同步方法push和pop只能有一个在执行  
  19.    * @author wulihai  
  20.    */  
  21. class SyncStack{       
  22.     private int index = 0;      
  23.     private char []data = new char[6];        
  24.        
  25.     public synchronized void push(char c){      
  26.         if(index == data.length){      
  27.         try{      
  28.                 this.wait();      
  29.         }catch(InterruptedException e){}      
  30.         }      
  31.         this.notify();      
  32.         data[index] = c;      
  33.         index++;      
  34.     }      
  35.     public synchronized char pop(){      
  36.         if(index ==0){      
  37.             try{      
  38.                 this.wait();      
  39.             }catch(InterruptedException e){}      
  40.         }      
  41.         this.notify();      
  42.         index--;      
  43.         return data[index];      
  44.     }      
  45. }      
  46.      
  47.      
  48. class  Producer implements Runnable{      
  49.     SyncStack stack;          
  50.     public Producer(SyncStack s){      
  51.         stack = s;      
  52.     }      
  53.     public void run(){      
  54.         for(int i=0; i<20; i++){      
  55.             char c =(char)(Math.random()*26+'A');//      
  56.             stack.push(c);      
  57.             System.out.println("produced:"+c);      
  58.             try{                                          
  59.                 Thread.sleep((int)(Math.random()*1000)); //随机休息,这样看起来生产和消费的产品个数都是随机的     
  60.             }catch(InterruptedException e){      
  61.             }      
  62.         }      
  63.     }      
  64. }      
  65.      
  66.      
  67. class Consumer implements Runnable{      
  68.     SyncStack stack;          
  69.     public Consumer(SyncStack s){      
  70.         stack = s;      
  71.     }      
  72.     public void run(){      
  73.         for(int i=0;i<20;i++){      
  74.             char c = stack.pop();      
  75.             System.out.println("消费:"+c);      
  76.             try{                                             
  77.                 Thread.sleep((int)(Math.random()*1000));//随机休息,这样看起来生产和消费的产品个数都是随机的        
  78.             }catch(InterruptedException e){      
  79.             }      
  80.         }      
  81.     }      
  82. }    
package com.wlh;

public class ProduceConsumer {   
    public static void main(String args[]){   
            SyncStack stack = new SyncStack();   
            Runnable p=new Producer(stack);   
            Runnable c = new Consumer(stack);   
            Thread t1 = new Thread(p);   
            Thread t2 = new Thread(c);   
            t1.start();   
            t2.start();   
    }   
}   
  
  /**
   * 支持多线程同步操作的堆栈的实现 
   * 因为只有一个线程能够锁定当前对象,而同步方法的执行前先锁定当前对象,
   * 所以同一时刻,同步方法push和pop只能有一个在执行
   * @author wulihai
   */
class SyncStack{    
    private int index = 0;   
    private char []data = new char[6];     
    
    public synchronized void push(char c){   
        if(index == data.length){   
        try{   
                this.wait();   
        }catch(InterruptedException e){}   
        }   
        this.notify();   
        data[index] = c;   
        index++;   
    }   
    public synchronized char pop(){   
        if(index ==0){   
            try{   
                this.wait();   
            }catch(InterruptedException e){}   
        }   
        this.notify();   
        index--;   
        return data[index];   
    }   
}   
  
  
class  Producer implements Runnable{   
    SyncStack stack;       
    public Producer(SyncStack s){   
        stack = s;   
    }   
    public void run(){   
        for(int i=0; i<20; i++){   
            char c =(char)(Math.random()*26+'A');//   
            stack.push(c);   
            System.out.println("produced:"+c);   
            try{                                       
                Thread.sleep((int)(Math.random()*1000)); //随机休息,这样看起来生产和消费的产品个数都是随机的  
            }catch(InterruptedException e){   
            }   
        }   
    }   
}   
  
  
class Consumer implements Runnable{   
    SyncStack stack;       
    public Consumer(SyncStack s){   
        stack = s;   
    }   
    public void run(){   
        for(int i=0;i<20;i++){   
            char c = stack.pop();   
            System.out.println("消费:"+c);   
            try{                                          
                Thread.sleep((int)(Math.random()*1000));//随机休息,这样看起来生产和消费的产品个数都是随机的     
            }catch(InterruptedException e){   
            }   
        }   
    }   
}  





死锁:当一个或多个进程等待系统资源,而系统资源又同时被此进程本身或者其它进程占用


例:结果2个线程谁都不打印输出数据

Java代码 复制代码
  1. package com.wlh;   
  2.   
  3. public class DeadLock extends Thread {   
  4.   
  5.        
  6.     int flag=0;   
  7.     static Object o1=new Object();   
  8.     static Object o2=new Object();   
  9.        
  10.     public DeadLock(int flag){   
  11.         this.flag=flag;   
  12.     }   
  13.     @Override  
  14.     public void run() {   
  15.         if(this.flag==1){   
  16.             synchronized(o1){   
  17.                 System.out.println(Thread.currentThread().getName()+"锁定对象o1");   
  18.                 try {   
  19.                     Thread.sleep(1000);//让另一个线程能进入另一块区域,锁定对象o2   
  20.                 } catch (InterruptedException e) {   
  21.                     e.printStackTrace();   
  22.                 }   
  23.                 synchronized(o2){   
  24.                     System.out.print("this.flag="+this.flag);   
  25.                 }   
  26.             }   
  27.                
  28.         }   
  29.         if(this.flag==2){   
  30.             synchronized(o2){   
  31.                 System.out.println(Thread.currentThread().getName()+"锁定对象o2");   
  32.                 try {   
  33.                     Thread.sleep(1000);//让另一个线程能进入另一块区域,锁定对象o1   
  34.                 } catch (InterruptedException e) {   
  35.                     e.printStackTrace();   
  36.                 }   
  37.                 synchronized(o1){   
  38.                     System.out.print("this.flag="+this.flag);   
  39.                 }   
  40.                    
  41.             }   
  42.         }   
  43.     }   
  44.   
  45.     public  static void main(String []args){   
  46.         DeadLock d1=new DeadLock(1);   
  47.         DeadLock d2=new DeadLock(2);   
  48.         d1.start();   
  49.         d2.start();   
  50.     }   
  51. }  
package com.wlh;

public class DeadLock extends Thread {

	
	int flag=0;
	static Object o1=new Object();
	static Object o2=new Object();
	
	public DeadLock(int flag){
		this.flag=flag;
	}
	@Override
	public void run() {
		if(this.flag==1){
			synchronized(o1){
				System.out.println(Thread.currentThread().getName()+"锁定对象o1");
				try {
					Thread.sleep(1000);//让另一个线程能进入另一块区域,锁定对象o2
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized(o2){
					System.out.print("this.flag="+this.flag);
				}
			}
			
		}
		if(this.flag==2){
			synchronized(o2){
				System.out.println(Thread.currentThread().getName()+"锁定对象o2");
				try {
					Thread.sleep(1000);//让另一个线程能进入另一块区域,锁定对象o1
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				synchronized(o1){
					System.out.print("this.flag="+this.flag);
				}
				
			}
		}
	}

	public  static void main(String []args){
		DeadLock d1=new DeadLock(1);
		DeadLock d2=new DeadLock(2);
		d1.start();
		d2.start();
	}
}






Join方法:将某个子线程合并到主线程,即等子线程全部运行全部执行完之后才执行主线程
例1:

Java代码 复制代码
  1. package com.wlh;   
  2.   
  3. public class TestJoin {   
  4.   public static void main(String[] args) {   
  5.     MyThread2 t1 = new MyThread2("子线程");   
  6.     t1.start();   
  7.      /*    try {  
  8.         t1.join();  
  9.     } catch (InterruptedException e) {}*/  
  10.            
  11.     for(int i=1;i<=10;i++){   
  12.         try {   
  13.             Thread.sleep(1000);//当前线程休息1000秒   
  14.             System.out.println("i am main thread");   
  15.         } catch (InterruptedException e) {   
  16.             e.printStackTrace();   
  17.         }   
  18.          
  19.     }   
  20.   }   
  21. }   
  22. class MyThread2 extends Thread {   
  23.   MyThread2(String s){   
  24.     super(s);   
  25.   }   
  26.      
  27.   public void run(){   
  28.     for(int i =1;i<=10;i++){   
  29.       System.out.println("i am "+getName());   
  30.       try {   
  31.         sleep(1000);//当前线程休息1000秒   
  32.       } catch (InterruptedException e) {   
  33.         return;   
  34.       }   
  35.     }   
  36.   }   
  37. }  
package com.wlh;

public class TestJoin {
  public static void main(String[] args) {
    MyThread2 t1 = new MyThread2("子线程");
    t1.start();
     /*    try {
    	t1.join();
    } catch (InterruptedException e) {}*/
    	
    for(int i=1;i<=10;i++){
    	try {
			Thread.sleep(1000);//当前线程休息1000秒
			System.out.println("i am main thread");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
      
    }
  }
}
class MyThread2 extends Thread {
  MyThread2(String s){
  	super(s);
  }
  
  public void run(){
    for(int i =1;i<=10;i++){
      System.out.println("i am "+getName());
      try {
      	sleep(1000);//当前线程休息1000秒
      } catch (InterruptedException e) {
      	return;
      }
    }
  }
}




备注:子线程和主线程交替执行
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread
i am 子线程
i am main thread 
例2:在 t1.start()子线程就绪;之后添加t1.join(),则等t1线程执行完之后才执行主线程

Java代码 复制代码
  1. package com.wlh;   
  2.   
  3. public class TestJoin {   
  4.   public static void main(String[] args) {   
  5.     MyThread2 t1 = new MyThread2("子线程");   
  6.     t1.start();   
  7.       try {   
  8.         t1.join();   
  9.     } catch (InterruptedException e) {}        
  10.     for(int i=1;i<=10;i++){   
  11.         try {   
  12.             Thread.sleep(1000);//当前线程休息1000秒   
  13.             System.out.println("i am main thread");   
  14.         } catch (InterruptedException e) {   
  15.             e.printStackTrace();   
  16.         }   
  17.          
  18.     }   
  19.   }   
  20. }   
  21. class MyThread2 extends Thread {   
  22.   MyThread2(String s){   
  23.     super(s);   
  24.   }   
  25.      
  26.   public void run(){   
  27.     for(int i =1;i<=10;i++){   
  28.       System.out.println("i am "+getName());   
  29.       try {   
  30.         sleep(1000);//当前线程休息1000秒   
  31.       } catch (InterruptedException e) {   
  32.         return;   
  33.       }   
  34.     }   
  35.   }   
  36. }  
package com.wlh;

public class TestJoin {
  public static void main(String[] args) {
    MyThread2 t1 = new MyThread2("子线程");
    t1.start();
      try {
    	t1.join();
    } catch (InterruptedException e) {}    	
    for(int i=1;i<=10;i++){
    	try {
			Thread.sleep(1000);//当前线程休息1000秒
			System.out.println("i am main thread");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
      
    }
  }
}
class MyThread2 extends Thread {
  MyThread2(String s){
  	super(s);
  }
  
  public void run(){
    for(int i =1;i<=10;i++){
      System.out.println("i am "+getName());
      try {
      	sleep(1000);//当前线程休息1000秒
      } catch (InterruptedException e) {
      	return;
      }
    }
  }
}


输出结果:

i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am 子线程
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread
i am main thread



Yeild方法:当前线程让出CPU的时间给其他线程执行一会。注意:是让出一会儿,待会又回来了。。。

Java代码 复制代码
  1.   
  2. package com.wlh;   
  3. public class TestYield {   
  4.   public static void main(String[] args) {   
  5.     MyThread3 t1 = new MyThread3("t1");   
  6.     MyThread3 t2 = new MyThread3("t2");   
  7.     t1.start(); t2.start();   
  8.   }   
  9. }   
  10. class MyThread3 extends Thread {   
  11.   MyThread3(String s){super(s);}   
  12.   public void run(){   
  13.     for(int i =1;i<=100;i++){   
  14.       System.out.println(getName()+": "+i);   
  15.       if(i%10==0){   
  16.         yield();   
  17.       }   
  18.     }   
  19.   }   
  20. }  
package com.wlh;
public class TestYield {
  public static void main(String[] args) {
    MyThread3 t1 = new MyThread3("t1");
    MyThread3 t2 = new MyThread3("t2");
    t1.start(); t2.start();
  }
}
class MyThread3 extends Thread {
  MyThread3(String s){super(s);}
  public void run(){
    for(int i =1;i<=100;i++){
      System.out.println(getName()+": "+i);
      if(i%10==0){
        yield();
      }
    }
  }
}


输出结果:只要一个线程执行到10的整数倍,必然让出CPU的时间给其他线程执行一会
t1: 1
t1: 2
t1: 3
t1: 4
t1: 5
t1: 6
t1: 7
t1: 8
t1: 9
t1: 10
t2: 1
t2: 2
t2: 3
t2: 4
t2: 5
t2: 6
t2: 7
t2: 8
t2: 9
t2: 10
t1: 11
t1: 12
t1: 13
t1: 14
t1: 15
t1: 16
t1: 17
t1: 18
t1: 19
t1: 20
t2: 11
t2: 12
t2: 13
t2: 14
t2: 15
...........
..............
................... 


 

 

分享到:
评论

相关推荐

    Java线程讲解Java线程讲解

    Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解Java线程讲解

    线程 JAVA java线程 java线程第3版 java线程第2版第3版合集

    电子书相关:包含4个有关JAVA线程的电子书(几乎涵盖全部有关线程的书籍) OReilly.Java.Threads.3rd.Edition.Sep.2004.eBook-DDU Java Thread Programming (Sams) java线程第二版中英文 java线程第二版中英文 ...

    java多线程编程总结

    Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的线程 ...

    Java线程详解大全

    Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程Java线程

    Java线程Java线程Java线程Java线程

    Java线程Java线程Java线程Java线程Java线程Java线程

    Java多线程编程总结

    Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的...

    JAVA线程停止的方法

    JAVA线程停止的方法

    java 线程java 线程

    java 线程java 线程java 线程java 线程java 线程java 线程java 线程java 线程java 线程

    java多线程笔记

    Java线程:概念与原理 2 一、操作系统中线程和进程的概念 2 二、Java中的线程 3 三、Java中关于线程的名词解释 3 四、线程的状态转换和生命周期 4 Java线程:创建与启动 7 Java线程:线程名称的设定及获取 10 Java...

    Java线程模块Java线程之秒表

    Java线程模块Java线程之秒表新手学习Java线程模块时,利用Java中设置线程的暂停间隔,做的简易秒表

    java线程同步java线程同步

    java线程同步java线程同步java线程同步

    java 线程 dump 分析工具 2.3.3

    java 线程Dump 分析工具: Java的TDA线程转储分析器是一个用于分析Sun Java VM生成的线程转储和堆信息的小型Swing GUI(目前用1.4测试)。它从提供的日志文件中解析线程转储和类直方图。它提供关于发现的线程转储的...

    java线程 线程学习资料 java线程教程

    java线程 线程 教程 java线程教程 java线程学习资料 本教程有什么内容? 本教程研究了线程的基础知识— 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单 程序。 我们还将研究更复杂的、使用线程的应用...

    Java的线程和Java AppletJava的线程和Java AppletJava的线程和Java Applet

    Java的线程和Java AppletJava的线程和Java AppletJava的线程和Java AppletJava的线程和Java AppletJava的线程和Java Applet

    java的多线程使用方法

    java多线程的使用方法如何使用,怎么使用,使用过程中有什么要注意的

    java线程.pdf

    java线程.pdf java 学习java

    java 多线程设计模式 进程详解

    《Java线程 高清晰中文第二版》中文第二版(PDF) 前言 第一章 线程简介 Java术语 线程概述 为什么要使用线程? 总结 第二章 Java线程API 通过Thread类创建线程 使用Runable接口的线程 线程的生命周期 线程命名 ...

    Java多线程--等待所有子线程执行完的五种方法.docx

    Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程执行完的五种方法 Java多线程--等待所有子线程...

    Java线程Java线程

    java 线程 新手java 线程 新手java 线程 新手java 线程 新手

    Java 模拟线程并发

    Java 模拟线程并发 Java, 模拟线程并发,线程,并发 Java, 模拟线程并发,线程,并发 Java, 模拟线程并发,线程,并发 Java, 模拟线程并发,线程,并发

Global site tag (gtag.js) - Google Analytics