java wait 函数_java 线程 Thread 使用介绍,包含wait(),notifyAll() 等函数使用介绍

(原创,转载请说明出处!谢谢--http://www.cnblogs.com/linguanh/)

此文目的为了帮助大家较全面、通俗地了解线程 Thread 相关基础知识!

目录:

--线程的创建:

--启动线程

--线程的调度

--Thread 类的简介

--线程的同步/异步

--wait() 和 notify(),notifyAll()方法

在讲线程之前,先说下进程。

进程:是运行系统中,每个独立运行的程序。例如win7,我既用酷狗软件听歌,又玩 LOL 游戏,又上QQ,那么这就有3个进程。

线程:一个进程里面有很多线程,进程是由线程组成的,线程的结束不一定会导致进程结束,而一个进程的结束,则会连带它里面的所有线程被结束。

------------线程的创建:

创建->

java 中有两种方式:

1,一种是通过实现Runnable 接口

2,另一种是继承线程类 Thread

实现Runnable接口的实例代码:

1 class threadT implementsRunnable{2 @Override3 public voidrun() {4 //在这编辑要执行的代码

5 }6 }

上述代码,通过实现 Runnable 的接口,重写接口函数 run() 来实现新建一个线程。类比,点击事件的接口 OnClickListener

实现:

1 Thread thread_test = new Thread(newthreadT);2 //实例化代码一般放在主线程中,例如 main 中 或 onCreate()

继承线程类Thread 的实例代码:

1 class threadT1 extendsThread{2 public voidrun(){3 // edit your code

4 }5 }

实现:

1 Thread thread_test = new ThreadT1();

thread_test.start();

上述两种方法的比较:

本人建议使用第一种,即使用实现Runnable 接口的方法来新建线程。

原因:

1:避免java 的单一 继承带来的局限;

2:和 onClickListener 点击事件一样,当你有多个线程时,使用Runnable 再在run内用一个 switch 就能分开使用;

--------------启动线程:

线程的启动一般都是通过方法执行 statrt() 进行的。

完整 main 函数测试代码:

1 packagecom.LGH.ew;2

3 /**

4 * Created by Administrator on 2015/4/25.5 * 各线程,当主线程main 执行完了,它们还会继续执行,彼此不影响6 * 多线程卖票 显示 demo,by LinGuanHong7 */

8 public classthreadTest {9 public static voidmain(String[] args){10 threadT t1 = new threadT1();//线程 1

11 Thread t2 = new Thread(new ThreadT());//线程 2

12

13 t2.start();14 t1.start();15 }16 }

------------线程的调度:

调度是什么意思呢?就是 cpu 执行每个线程的顺序,注意,不一定是按顺序的,这个和线程的优先级有关!

线程的调用是统一由JVM根据时间片来调度的,其执行顺序随机。大致执行流程如下:

2764a78e88fb2dc59c9ab337900b6d93.png

由上述可以看出, jvm 在执行多线程 程序的时候,在某一个时间段,其实也是只能运行一个线程,

但是它用划分时间片段的机制来转换调用各个线程,这个时间片段很短!

-----------Thread 类的简介

java.lang.Thread 类:

常用的方法有:

---public void start(); 启动该线程,其中调用了这个方法不一定就立即进行,还要看是否被调度到;

---public static Thread currentThread(); 静态方法,这个方法很重要,用来返回当前正在执行的线程对象引用;

---public final booleann isAlive();测试线程是否还活着;

---public Thread.State getState();返回该线程当前的状态,

分别有:

NEW 实例化了,但尚未启动的线程是这种状态,新建 态;

RUNNABLE 正在被执行的状态;

BLOCKED 受阻塞并等待某个监视器锁的线程态;

WAITING 无限期地等待另外一个线程来执行特地操作,等待 态;

TIMED_WAITING 等待另一个线程来执行取决于指定等待时间的操作,超时等待 态

TERMINATED 已退出的线程的状态,终止 态。

---public final String getName();返回线程名称,一般和setName(),连用;

---public final void setDaemon(boolean on);将该线程标记为守护线程;

---public static void sleep(long millis);在指定的毫秒内,让该线程暂停;

---public final void setPriority(int level);设置线程的优先级,可以是 1,5,10,分别是 低、普通、最高,默认是 5 ;

---public static void yield();线程让步,它会暂停该线程,把执行的机会让给相同或优先级更高的线程;

---public void final join();把某线程加入到某线程中去,被加者变为子线程;

---public void interrupt(); 中断线程.

------------线程的生命周期

其生命周期可以总结为上面的 6个 状态,图解如下:

4969b48e39387114c4083d7bb3aa3004.png

-------------线程的同步/异步

下面通过demo 代码说明,内涵synchronized 保护机制:

1 packagecom.LGH.ew;2

3 /**

4 * Created by Administrator on 2015/4/25.5 * 各线程,当主线程main 执行完了,它们还会继续执行,彼此不影响6 * 多线程卖票 显示 demo,by LinGuanHong7 */

8 public class threadTest { //卖火车票例子

9 public static voidmain(String[] args){10 threadT T = newthreadT();11 Thread t1 = new Thread(T);//线程 1

12 t1.setName("1");//设置 线程名字13 //t1.getState(); 这里有具体的线程对象,所以可以直接使用其类方法;

14 t1.start();15 Thread t2 = new Thread(T);//线程 2

16 t2.setName("2");17 t2.start();18 Thread t3 = new Thread(T);//线程 3

19 t3.setName("3");20 t3.start();21 Thread t4 = new Thread(T);//线程 4

22 t4.setName("4");23 t4.start();24 Thread t5 = new Thread(T);//线程 5

25 t5.setName("5");26 t5.start();27 }28 }29 class threadT implements Runnable{ //实例化接口

30 private int tickets = 0;31 @Override32 public voidrun() {33 boolean control = true;34 while(control){35 control = sell();//调用sell 方法,大家可以通过改变这个函数的调用,来看异步、同步的效果

36 }37 }38

39 public boolean sell(){//异步线程机制,会被打断,所谓打断,就是会出现 线程1 卖了第2张票时,线程3也卖了第2 张

40 boolean control = true;41 if(tickets<100){42 tickets ++;43 //在函数内,如果没有具体的线程对象,就要使用静态方法 currentThread() 返回当前正在执行的线程对象的引用,在使用类方法

44 System.out.println(Thread.currentThread().getName()+":"+tickets);//同上

45 Thread.State state = Thread.currentThread().getState();//同上

46 System.out.println("State:"+state.toString());//输出当前的状态,正常是 runnable

47 }else{48 control = false;49 }50 try{51 Thread.sleep(1);52 }catch(Exception e){53 e.printStackTrace();54 }55 returncontrol;56 }57

58 //关键字 - synchronized 保护 当前 函数在执行时不被其他线程打断,同步线程机制59 //整体同步,效率低

60 public synchronized booleansell1(){61 boolean control = true;62 if(tickets<100){63 tickets ++;64 //在函数内,如果没有具体的线程对象,就要使用静态方法 currentThread() 返回当前正在执行的线程对象的引用,在使用类方法

65 System.out.println(Thread.currentThread().getName()+":"+tickets);//同上

66 Thread.State state = Thread.currentThread().getState();//同上67 //System.out.println("State:"+state.toString());

68 }else{69 control = false;70 }71 try{72 Thread.sleep(1);73 }catch(Exception e){74 e.printStackTrace();75 }76 returncontrol;77 }78 //关键字 - synchronized 实质是一个对象锁

79

80 public boolean sell2(){ //条件 关键字 - synchronized 保护 当前 函数在执行时不被其他线程打断,同步线程机制

81 boolean control = true;82 synchronized(this) { //仅仅同步会操作到的共同部分变量,tickets,这样避免同步整体,提高效率

83 if (tickets < 100) {84 tickets++;85 //在函数内,如果没有具体的线程对象,就要使用静态方法 currentThread() 返回当前正在执行的线程对象的引用,在使用类方法

86 System.out.println(Thread.currentThread().getName() + ":" + tickets);//同上

87 Thread.State state = Thread.currentThread().getState();//同上88 //System.out.println("State:"+state.toString());

89 } else{90 control = false;91 }92 }93 try{94 Thread.sleep(1);95 }catch(Exception e){96 e.printStackTrace();97 }98 returncontrol;99 }100 }

-------------wait() 和 notify(),notifyAll()方法

他们是同步机制中的重要部分,必须和 synchronized 关键字结合使用,即在 synchronized 代码块中使用!

否在 抛出 Illegal..... 非法异常。

wait() 被调用,当前线程将会被中断运行,并且放弃该对象的锁;

执行了 notify() 后,会唤醒此对象等待池中的某个线程,使之成为可运行的线程;

notifyAll()则唤醒所有;

下面用一个具体的demo 说明:

前言-------------

生产者和消费者的问题,生产者将产品交给店员,而消费者从店员处取走产品,店员一次只能持有固定的产品,如果生产者生产过多了的产品,店员会叫生产者等一下,如果店中有空位放产品了再通知生产者继续生产;

如果店中供不应求,店员会叫消费者等一会,等生产者生产了再叫消费者来拿。

问题:

生产者生产过快,消费者会漏掉一些,没取到;

消费者比生产者快,消费者会拿到相同的;

1 packagecom.LGH.ew.view;2

3 /**

4 * Created by Administrator on 2015/4/25.5 */

6 public class Product { //生产者、消费者问题

7 public static voidmain(String[] args){8 clerk c = newclerk();9 Thread productT = new Thread(new Producer(c));//生产者线程

10 Thread consumerT = new Thread(new Consumer(c));//消费者线程

11 productT.start();12 consumerT.start();13 }14 }15 class clerk{ //店员

16 private int product = 0; //默认 0 个产品

17 public synchronized void addproduct(){ //生产出的产品,交给店员

18 if(this.product>=20){19 try{20 wait(); //产品过多,稍后再生产

21 }catch(Exception e){22 e.printStackTrace();23 }24 }else{25 product++;26 System.out.println("生产者生产第"+product+"个产品。");27 notifyAll(); //通知等待区的消费者可取产品

28 }29 }30 public synchronized void getproduct(){ //消费者从店员处取产品

31 if(this.product<=0){32 try{33 wait(); //缺货,稍后再取

34 }catch(Exception e){35 e.printStackTrace();36 }37 }else{38 System.out.println("消费者取走了第:" + product + "产品。");39 product--;40 notifyAll(); //通知等待取得生产者可以继续生产

41 }42 }43 }44

45 class Producer implements Runnable{ //生产者线程

46

47 privateclerk c;48 publicProducer(clerk c){49 this.c =c;50 }51 @Override52 public voidrun() {53 System.out.println("生产者开始生产产品。");54 while(true){55 try{56 Thread.sleep((int)(Math.random()*10)*100);57 }catch(Exception e){58 e.printStackTrace();59 }60 c.addproduct(); //生产

61 }62 }63 }64

65 class Consumer implements Runnable{ //消费者线程

66

67 privateclerk c ;68

69 publicConsumer(clerk c){70 this.c =c;71 }72 @Override73 public voidrun() {74 System.out.println("消费者开始取走产品。");75 while(true){76 try{77 Thread.sleep((int)(Math.random()*10)*100);78 }catch(Exception e){79 e.printStackTrace();80 }81 c.getproduct(); //取产品

82 }83 }84 }

全文终,各位如果觉得还可以的话,请帮忙点个赞,让更多人能看到。谢谢

4698773.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值