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 implements Runnable{ 2 @Override 3 public void run() { 4 //在这编辑要执行的代码 5 } 6 }
上述代码,通过实现 Runnable 的接口,重写接口函数 run() 来实现新建一个线程。类比,点击事件的接口 OnClickListener
实现:
1 Thread thread_test = new Thread(new threadT); 2 //实例化代码一般放在主线程中,例如 main 中 或 onCreate()
继承线程类Thread 的实例代码:
1 class threadT1 extends Thread{ 2 public void run(){ 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 package com.LGH.ew; 2 3 /** 4 * Created by Administrator on 2015/4/25. 5 * 各线程,当主线程main 执行完了,它们还会继续执行,彼此不影响 6 * 多线程卖票 显示 demo,by LinGuanHong 7 */ 8 public class threadTest { 9 public static void main(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根据时间片来调度的,其执行顺序随机。大致执行流程如下:
由上述可以看出, 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个 状态,图解如下:
-------------线程的同步/异步
下面通过demo 代码说明,内涵 synchronized 保护机制:
1 package com.LGH.ew; 2 3 /** 4 * Created by Administrator on 2015/4/25. 5 * 各线程,当主线程main 执行完了,它们还会继续执行,彼此不影响 6 * 多线程卖票 显示 demo,by LinGuanHong 7 */ 8 public class threadTest { //卖火车票例子 9 public static void main(String[] args){ 10 threadT T = new threadT(); 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 @Override 32 public void run() { 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 return control; 56 } 57 58 //关键字 - synchronized 保护 当前 函数在执行时不被其他线程打断,同步线程机制 59 //整体同步,效率低 60 public synchronized boolean sell1(){ 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 return control; 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 return control; 99 } 100 }
-------------wait() 和 notify(),notifyAll()方法
他们是同步机制中的重要部分,必须和 synchronized 关键字结合使用,即在 synchronized 代码块中使用!
否在 抛出 Illegal..... 非法异常。
wait() 被调用,当前线程将会被中断运行,并且放弃该对象的锁;
执行了 notify() 后,会唤醒此对象等待池中的某个线程,使之成为可运行的线程;
notifyAll()则唤醒所有;
下面用一个具体的demo 说明:
前言-------------
生产者和消费者的问题,生产者将产品交给店员,而消费者从店员处取走产品,店员一次只能持有固定的产品,如果生产者生产过多了的产品,店员会叫生产者等一下,如果店中有空位放产品了再通知生产者继续生产;
如果店中供不应求,店员会叫消费者等一会,等生产者生产了再叫消费者来拿。
问题:
生产者生产过快,消费者会漏掉一些,没取到;
消费者比生产者快,消费者会拿到相同的;
1 package com.LGH.ew.view; 2 3 /** 4 * Created by Administrator on 2015/4/25. 5 */ 6 public class Product { //生产者、消费者问题 7 public static void main(String[] args){ 8 clerk c = new clerk(); 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 private clerk c; 48 public Producer(clerk c){ 49 this.c = c; 50 } 51 @Override 52 public void run() { 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 private clerk c ; 68 69 public Consumer(clerk c){ 70 this.c = c; 71 } 72 @Override 73 public void run() { 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 }
全文终,各位如果觉得还可以的话,请帮忙点个赞,让更多人能看到。谢谢
如果您认为这篇文章还不错或者有所收获,您可以通过扫描一下下面的支付宝二维码 打赏我一杯咖啡【物质支持】,也可以点击右下角的【推荐】按钮【精神支持】,因为这两种支持都是我继续写作,分享的最大动力
、
java 线程 Thread 使用介绍,包含wait(),notifyAll() 等函数使用介绍相关推荐
- Java线程 Thread 的6种状态以及转变过程
线程的6种状态以及转变: java的线程一共6种状态.具体代码见: java.lang.Thread.State 1 NEW 新建状态 Thread state for a thread which ...
- JAVA线程间协作:wait.notify.notifyAll
欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...
- python介绍和用途-python匿名函数的介绍及用途
匿名函数 用lambda能够创建一个匿名函数,这种函数得名于省略了用def声明函数的标准步骤. 语法 lambda [arg1 [,arg2,.....argn]]:expression 如何使用 我 ...
- java线程学习之notify方法和notifyAll方法
notify(通知)方法,会将等待队列中的一个线程取出.比如obj.notify();那么obj的等待队列中就会有一个线程选中并且唤醒,然后被唤醒的队列就会退出等待队列.活跃线程调用等待队列中的线程时 ...
- java 线程 Thread Runnable 实现样例
1: /** * Thread 实现多线程样例(可继承) */ public class ThreadImplementsTest implements Runnable{ public ...
- java 线程 thread.join_java线程Thread的join方法。
1,方法的作用: 父线程等待子线程的执行. 如果是join或者join(0),即等待时长是0,父线程就会一直等到子线程执行结束, 如果是join(time),即等待时长是time数值,那父线程实际等待 ...
- java 线程的销毁_Java 线程(1)- 创建与销毁
Java 采用 thread-per-task 的线程模型,即一个任务(一段代码)对应一个 Java 线程(thread),而一个 Java 线程对应一个操作系统线程,所以了解一些操作系统进程的管理知 ...
- Java判断字符串中是否包含中英文标点符号
Java判断字符串中是否包含中英文标点符号 /*** 该函数判断一个字符串是否包含标点符号(中文英文标点符号).* 原理是原字符串做一次清洗,清洗掉所有标点符号.* 此时,如果原字符串包含标点符号,那 ...
- JAVA线程池原理以及几种线程池类型介绍
在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.将需处理的任务的数量大 使用线程池的好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销 2.如不使用线程池, ...
最新文章
- 常用的Java GC算法
- 大量LAST_ACK 的分析过程
- 龙芯.NET正式发布 稳步推进生态建设
- 2021年度邵逸夫数学科学奖
- LeetCode MySQL刷题——day2
- laravel 下载报错:Unable to guess the mime type as no guessers are available
- 二级菜单不同方法的实现
- linux innode节点读取,混沌工程之注入磁盘innode耗尽
- null和空 not null
- 今天再发一下热门关键字,看看能否推广网站
- 「电商干货」分销爆单的6个步骤
- IDEA Unable to import maven project: See logs for details具体解决方法
- Google网络硬盘GDrive在几个月内即将成真?!
- html5 mp4转换ogv格式,如何将mp4视频转换成ogv高清视频呢
- jsch jar包连接不上ssh报Algorithm negotiation fail 错误
- Dev C++ 下载
- 51单片机定时器介绍
- 回顾维乐VELO创始人余彩云漫漫创新路
- tmac v6设置中文_Technitium MAC Address Changer(mac地址修改器) 免费版v6.0.7
- 用友网络并购秉钧网络 加速布局企业互联网服务