(原创,转载请说明出处!谢谢--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() 等函数使用介绍相关推荐

  1. Java线程 Thread 的6种状态以及转变过程

    线程的6种状态以及转变: java的线程一共6种状态.具体代码见: java.lang.Thread.State 1 NEW 新建状态 Thread state for a thread which ...

  2. JAVA线程间协作:wait.notify.notifyAll

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  3. python介绍和用途-python匿名函数的介绍及用途

    匿名函数 用lambda能够创建一个匿名函数,这种函数得名于省略了用def声明函数的标准步骤. 语法 lambda [arg1 [,arg2,.....argn]]:expression 如何使用 我 ...

  4. java线程学习之notify方法和notifyAll方法

    notify(通知)方法,会将等待队列中的一个线程取出.比如obj.notify();那么obj的等待队列中就会有一个线程选中并且唤醒,然后被唤醒的队列就会退出等待队列.活跃线程调用等待队列中的线程时 ...

  5. java 线程 Thread Runnable 实现样例

    1: /**  * Thread  实现多线程样例(可继承)  */ public class ThreadImplementsTest implements Runnable{     public ...

  6. java 线程 thread.join_java线程Thread的join方法。

    1,方法的作用: 父线程等待子线程的执行. 如果是join或者join(0),即等待时长是0,父线程就会一直等到子线程执行结束, 如果是join(time),即等待时长是time数值,那父线程实际等待 ...

  7. java 线程的销毁_Java 线程(1)- 创建与销毁

    Java 采用 thread-per-task 的线程模型,即一个任务(一段代码)对应一个 Java 线程(thread),而一个 Java 线程对应一个操作系统线程,所以了解一些操作系统进程的管理知 ...

  8. Java判断字符串中是否包含中英文标点符号

    Java判断字符串中是否包含中英文标点符号 /*** 该函数判断一个字符串是否包含标点符号(中文英文标点符号).* 原理是原字符串做一次清洗,清洗掉所有标点符号.* 此时,如果原字符串包含标点符号,那 ...

  9. JAVA线程池原理以及几种线程池类型介绍

    在什么情况下使用线程池? 1.单个任务处理的时间比较短      2.将需处理的任务的数量大 使用线程池的好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销      2.如不使用线程池, ...

最新文章

  1. 常用的Java GC算法
  2. 大量LAST_ACK 的分析过程
  3. 龙芯.NET正式发布 稳步推进生态建设
  4. 2021年度邵逸夫数学科学奖
  5. LeetCode MySQL刷题——day2
  6. laravel 下载报错:Unable to guess the mime type as no guessers are available
  7. 二级菜单不同方法的实现
  8. linux innode节点读取,混沌工程之注入磁盘innode耗尽
  9. null和空 not null
  10. 今天再发一下热门关键字,看看能否推广网站
  11. 「电商干货」分销爆单的6个步骤
  12. IDEA Unable to import maven project: See logs for details具体解决方法
  13. Google网络硬盘GDrive在几个月内即将成真?!
  14. html5 mp4转换ogv格式,如何将mp4视频转换成ogv高清视频呢
  15. jsch jar包连接不上ssh报Algorithm negotiation fail 错误
  16. Dev C++ 下载
  17. 51单片机定时器介绍
  18. 回顾维乐VELO创始人余彩云漫漫创新路
  19. tmac v6设置中文_Technitium MAC Address Changer(mac地址修改器) 免费版v6.0.7
  20. 用友网络并购秉钧网络 加速布局企业互联网服务

热门文章

  1. win2k cannot set the docm proportites
  2. 汇编实验注意点(待补充和更新)
  3. ubuntu 18.04设置系统自带系统截图快捷键
  4. Apache Beam和BigQuery的错误处理(Java SDK)
  5. Broadcom BCM4322(如:HP 6530b)wifi不能用解决办法
  6. Yii 框架学习--03 多应用多模块
  7. 目标检测之dpm---hog的最优升级版
  8. WordPress获取页面文章内容的代码
  9. H3C 多区域MSTP配置
  10. python ImportError: No module named unittest2