本文转载自51cto

一、线程的基本概念
简单的说:线程就是一个程序里不同的执行路径,在同一个时间点上cpu只会有一个线程在执行,Java里的多线程是通过java.lang.Thread类来实现的,每个线程都拥有自己独立的方法栈空间。

二、java线程的创建和启动
第一种
定义线程类实现Runnable接口:
Thread myThread = new Thread(target) //target为Runnable接口类型
Runnable中只有一个方法:
public void run();用以定义线程运行体
第二种
可以定义一个Thread的子类并重写其run方法:
clas MyThread extends Thread{
public void run(){}
}
线程类必须通过执行Thread的start()方法启动一个新的线程,如果调用run()方法是属于方法的调用,不会启动一个新的线程,推荐使用第一种方式创建线程,使用接口较为灵活。

三、线程状态装换
调用线程start()方法时,线程进入就绪状态,Cpu分配时间片,线程进入运行状态,时间片结束,run()方法未执行完,线程进入阻塞状态。

四、线程控制基本方法
 isAlive() //判断线程是否还“活着”,即线程是否还未终止
getPriority() //获得线程的优先级数值
setPriority() //设置线程的优先级指数
Thread.sleep() //静态方法,将当前线程睡眠指定毫秒数
join()  //调用某线程的该方法,将当前线程与该线程合并,
//即等待该线程结束,再回复当前线程的运行。
yield()  //让出CPU,当前线程进入就绪状态等待调度
interrupt() //中断线程
wait()  //当前线程进入对象的wait pool
notify()/notifyAll //唤醒对象的wait pool中的一个/所有等待线程

五、sleep方法
Thread的静态方法
public static void sleep(long millis)throws InterruptedException
必须对异常进行捕捉
Thread.currentThread();  //拿到当前线程

六、join和yield方法

t.join(); //t的run()方法完才会继续执行当前线程方法体
//也就是两个线程变成了一个线程

join方法的功能就是使异步执行的线程变成同步执行。也就是说,当调用线程实例的start方法后,这个方法会立即返回,如果在调用start方法后后需要使用一个由这个线程计算得到的值,就必须使用join方法。如果不使用join方法,就不能保证当执行到start方法后面的某条语句时,这个线程一定会执行完。

下面的代码演示了join的用法。

  1. package mythread;
  2.  
  3. public class JoinThread extends Thread
  4. {
  5. public static int n = 0;
  6.  
  7. static synchronized void inc()
  8. {
  9. n++;
  10. }
  11. public void run()
  12. {
  13. for (int i = 0; i < 10; i++)
  14. try
  15. {
  16. inc();
  17. sleep(3); // 为了使运行结果更随机,延迟3毫秒
  18.  
  19. }
  20. catch (Exception e)
  21. {
  22. }
  23. }
  24. public static void main(String[] args) throws Exception
  25. {
  26.  
  27. Thread threads[] = new Thread[100];
  28. for (int i = 0; i < threads.length; i++) // 建立100个线程
  29. threads[i] = new JoinThread();
  30. for (int i = 0; i < threads.length; i++) // 运行刚才建立的100个线程
  31. threads[i].start();
  32. if (args.length > 0)
  33. for (int i = 0; i < threads.length; i++) // 100个线程都执行完后继续
  34. threads[i].join();
  35. System.out.println("n=" + JoinThread.n);
  36. }
  37. }

在例程2-8中建立了100个线程,每个线程使静态变量n增加10。如果在这100个线程都执行完后输出n,这个n值应该是1000。

1.  测试1

使用如下的命令运行上面程序:

  1. java mythread.JoinThread

程序的运行结果如下:

n=442

这个运行结果可能在不同的运行环境下有一些差异,但一般n不会等于1000。从上面的结果可以肯定,这100个线程并未都执行完就将n输出了。

2.  测试2

使用如下的命令运行上面的代码:

在上面的命令行中有一个参数join,其实在命令行中可以使用任何参数,只要有一个参数就可以,这里使用join,只是为了表明要使用join方法使这100个线程同步执行。

程序的运行结果如下:

n=1000

无论在什么样的运行环境下运行上面的命令,都会得到相同的结果:n=1000。这充分说明了这100个线程肯定是都执行完了,因此,n一定会等于1000。

t.yield(); //暂停当前正在执行的线程对象,并执行其他线程。方法为静态
//哪个线程体执行此方法,哪个线程让步

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

七、interrupt方法一种让线程退出的方式。

  1. 1 import java.util.*;
  2. 2 public class TestInterrupt{
  3. 3 public static void main(String[] args){
  4. 4 MyThread t = new MyThread();
  5. 5 t.start();
  6. 6 try{Thread.sleep(10000);}
  7. 7 catch(InterruptedException i){}
  8. 8 t.interrupt();
  9. 9 }
  10. 10 }
  11. 11
  12. 12 class MyThread extends Thread{
  13. 13 public void run(){
  14. 14 while(true){
  15. 15 try{
  16. 16 System.out.println("------"+new Date()+"-----");
  17. 17 Thread.sleep(1000);
  18. 18 }catch(InterruptedException i){
  19. 19 return;
  20. 20 }
  21. 21 }
  22. 22 }
  23. 23 }
  24. 24

八、线程优先级别 
线程的优先级用数字表示,范围从1到10,一个线程的缺省优先级为5.
Thread.MAX_PRIORITY=1
Thread.MIN_PRIORITY=10
Thread.NORM_PRIORITY=5
例:t.setPriority(Thread.NORM_PRIORITY+3);
九、线程同步
1.同步代码块
synchronized(this){  //在执行代码块过程中,不会被其他线程打断
...  
}
public sunchronized void method //执行此方法时,当前对象被锁定
在Java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性,每个对象 都对应一个可称为"互斥锁"的标记,这个标记保证在任一时刻,只能有一个线程访 问该对象。
2.线程死锁

  1. public class TestDeadLock implements Runnable {
  2. public int flag = 1;
  3. static Object o1 = new Object(), o2 = new Object();
  4. public void run() {
  5. System.out.println("flag=" + flag);
  6. if(flag == 1) {
  7. synchronized(o1) {
  8. try {
  9. Thread.sleep(500);
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. }
  13. synchronized(o2) {
  14. System.out.println("1");
  15. }
  16. }
  17. }
  18. if(flag == 0) {
  19. synchronized(o2) {
  20. try {
  21. Thread.sleep(500);
  22. } catch (Exception e) {
  23. e.printStackTrace();
  24. }
  25. synchronized(o1) {
  26. System.out.println("0");
  27. }
  28. }
  29. }
  30. }
  31.  
  32. public static void main(String[] args) {
  33. TestDeadLock td1 = new TestDeadLock();
  34. TestDeadLock td2 = new TestDeadLock();
  35. td1.flag = 1;
  36. td2.flag = 0;
  37. Thread t1 = new Thread(td1);
  38. Thread t2 = new Thread(td2);
  39. t1.start();
  40. t2.start();
  41.  
  42. }
  43. }

十、生产者消费者问题

  1. public class ProducerConsumer {
  2. public static void main(String[] args) {
  3. SyncStack ss = new SyncStack();
  4. Producer p = new Producer(ss);
  5. Consumer c = new Consumer(ss);
  6. new Thread(p).start();
  7. new Thread(p).start();
  8. new Thread(p).start();
  9. new Thread(c).start();
  10. }
  11. }
  12.  
  13. class WoTou {
  14. int id;
  15. WoTou(int id) {
  16. this.id = id;
  17. }
  18. public String toString() {
  19. return "WoTou : " + id;
  20. }
  21. }
  22.  
  23. class SyncStack { //栈实现
  24. int index = 0;
  25. WoTou[] arrWT = new WoTou[6]; //相当于装物品的篮子
  26.  
  27. public synchronized void push(WoTou wt) { //生产物品,线程安全
  28. while(index == arrWT.length) { //当篮子满了线程等待
  29. try {
  30. this.wait();
  31. } catch (InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34.  
  35. }
  36. this.notifyAll(); //开始生产时,叫醒等待的其他线程开始消费
  37. arrWT[index] = wt;
  38. index ++;
  39. }
  40.  
  41. public synchronized WoTou pop() { //消费物品,线程安全
  42. while(index == 0) { //如果篮子空了
  43. try {
  44. this.wait(); //线程等待,等待生产者开始
  45. //生产,叫醒此线程
  46. } catch (InterruptedException e) {
  47. e.printStackTrace();
  48. }
  49.  
  50. }
  51. this.notifyAll(); //消费时喊醒生产者生产
  52. index--;
  53. return arrWT[index];
  54. }
  55. }
  56.  
  57. class Producer implements Runnable { //生产者类
  58. SyncStack ss = null;
  59. Producer(SyncStack ss) {
  60. this.ss = ss;
  61. }
  62.  
  63. public void run() {
  64. for(int i=0; i<20; i++) { //生产20个
  65. WoTou wt = new WoTou(i);
  66. ss.push(wt);
  67. System.out.println("生产了:" + wt);
  68. try {
  69. Thread.sleep((int)(Math.random() * 200));
  70. } catch (InterruptedException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. }
  75. }
  76.  
  77. class Consumer implements Runnable {
  78. SyncStack ss = null;
  79. Consumer(SyncStack ss) {
  80. this.ss = ss;
  81. }
  82.  
  83. public void run() {
  84. for(int i=0; i<20; i++) { //消费20个
  85. WoTou wt = ss.pop();
  86. System.out.println("消费了: " + wt);
  87. try {
  88. Thread.sleep((int)(Math.random() * 1000));
  89. } catch (InterruptedException e) {
  90. e.printStackTrace();
  91. }
  92. }
  93. }
  94. }

基础知识《四》---Java多线程学习总结的更多相关文章

  1. Java多线程学习(四)等待/通知(wait/notify)机制

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79690279 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  2. 转:Java多线程学习(总结很详细!!!)

    Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程 ...

  3. Java多线程学习(吐血超详细总结)

    Java多线程学习(吐血超详细总结) 林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实 ...

  4. [转]Java多线程学习(总结很详细!!!)

    Java多线程学习(总结很详细!!!) 此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢? 本文主要讲java中多线程 ...

  5. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

  6. Java多线程学习(转载)

    Java多线程学习(转载) 时间:2015-03-14 13:53:14      阅读:137413      评论:4      收藏:3      [点我收藏+] 转载 :http://blog ...

  7. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  8. Java多线程学习(六)Lock锁的使用

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

  9. Java多线程学习(五)线程间通信知识点补充

    系列文章传送门: Java多线程学习(二)synchronized关键字(1) Java多线程学习(二)synchronized关键字(2) Java多线程学习(三)volatile关键字 Java多 ...

  10. Java多线程学习(三)volatile关键字

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

随机推荐

  1. java ee 中文乱码的问题

    java ee 中文乱码的问题 发生中文乱码的三种情况 (一) 表单form Post 方法 直接在服务器中设置 request.setCharacterEncoding("utf-8&qu ...

  2. iOS边练边学--级联菜单的两种实现方法

    一.方法1:如图,图中的两个tableView分别交给两个控制器来管理 重点难点:categoryTableView被点击之后,subcategoryTableView要取得相应的数据进行刷新,所以s ...

  3. 教你一步一步实现一个Promise

    Promise我想现在大家都非常熟悉了,主要作用就是解决异步回调问题,这里简单介绍下. Promise规范是CommonJS规范之一,而Promise规范又分了好多种,比如 Promises/A.Pr ...

  4. UVA5876 Writings on the Wall 扩展KMP

    扩展KMP的简单题. #include<stdio.h> #include<string.h> #define maxn 51010 char s[maxn],t[maxn]; ...

  5. Java-try-catch-finally

    try-catch语句还可以包括第三部分,就是finally子句.它表示无论是否出现异常,都应当执行的内容.try-catch-finally语句的一般语法形式为: try { // 可能会发生异常的 ...

  6. 【SGU 104】Little shop of flowers

    题意 每个花按序号顺序放到窗口,不同窗口可有不同观赏值,所有花都要放上去,求最大观赏值和花的位置. 分析 dp,dp[i][j]表示前i朵花最后一朵在j位置的最大总观赏值. dp[i][j]=max( ...

  7. BZOJ1432 [ZJOI2009]Function

    Description Input 一行两个整数n; k. Output 一行一个整数,表示n 个函数第k 层最少能由多少段组成. Sample Input 1 1 Sample Output 1 H ...

  8. 洛谷P1082 同余方程

    题目描述 求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 输入输出格式 输入格式: 输入只有一行,包含两个正整数 a, b,用一个空格隔开. 输出格式: 输出只有一行,包含一个正 ...

  9. linux 下用户管理

    linux 下用户管理 一.用户的分类 1.超级用户:root UID=0 2.系统用户:不需要登录系统,对应用程序服务,主要维护系统的正常运行:UID = 1 ~ 499(RHEL7 = 1 ~ 9 ...

  10. Emgu学习之(一)——Emgu介绍

    OpenCV“OpenCV是一个开源的计算机视觉库.OpenCV采用C/C++语言编写,可以运行在Linux/Windows/Mac等操作系统上.OpenCV还提供了Python.Ruby.MATLA ...