黑马程序员java笔记之二-----多线程

简介: java中实现多线程操作有两种手段,一种继承自Thread类,另一种是实现Runnable接口。  一、继承Thread     Thread类是在java.lang包中定义的,一个类只要继承了Thread类,此类就称为多线程实现类。

java中实现多线程操作有两种手段,一种继承自Thread类,另一种是实现Runnable接口。

 一、继承Thread

    Thread类是在java.lang包中定义的,一个类只要继承了Thread类,此类就称为多线程实现类。在Thread子类中,必须明确地覆写Thread类中的run()方法,此方法为线程的主体。
[java]  view plaincopy
  1. <span style="font-size:18px;"> class MyThread extends Thread{    // 继承Thread类,作为线程的实现类  
  2.     private String name ;        // 表示线程的名称  
  3.     public MyThread(String name){  
  4.         this.name = name ;        // 通过构造方法配置name属性  
  5.     }  
  6.     public void run(){    // 覆写run()方法,作为线程 的操作主体  
  7.         for(int i=0;i<10;i++){  
  8.             System.out.println(name + "运行,i = " + i) ;  
  9.         }  
  10.     }  
  11.        }  
  12.      public class ThreadDemo01{  
  13.         public static void main(String args[]){  
  14.             MyThread mt1 = new MyThread("线程A ") ;     // 实例化对象  
  15.             MyThread mt2 = new MyThread("线程B ") ;     // 实例化对象  
  16.             mt1.run() ;    // 调用线程主体  
  17.             mt2.run() ;    // 调用线程主体  
  18.      }  
  19. }</span>  


二、实现Runnable接口,Runnable接口中只定义了,一个抽象方法。

       

[java]  view plaincopy
  1. class MyThread implements Runnable{    // 实现Runnable接口,作为线程的实现类  
  2.            private String name ;        // 表示线程的名称  
  3.   
  4.         public MyThread(String name){  
  5.             this.name = name ;        // 通过构造方法配置name属性  
  6.         }  
  7.         public void run(){    // 覆写run()方法,作为线程 的操作主体  
  8.             for(int i=0;i<10;i++){  
  9.                 System.out.println(name + "运行,i = " + i) ;  
  10.             }  
  11.         }  
  12.        }  
  13.         public class RunnableDemo01{  
  14.             public static void main(String args[]){  
  15.                  MyThread mt1 = new MyThread("线程A ") ;     // 实例化对象  
  16.                 MyThread mt2 = new MyThread("线程B ") ;     // 实例化对象  
  17.                 Thread t1 = new Thread(mt1) ;        // 实例化Thread类对象  
  18.                 Thread t2 = new Thread(mt2) ;        // 实例化Thread类对象  
  19.                 t1.start() ;    // 启动多线程  
  20.                 t2.start() ;    // 启动多线程  
  21.         }  
  22.     }  

三、线程间通信:  多个线程在操作同一个资源,但是操作的动作不同。等待唤醒机制:

 

[java]  view plaincopy
  1. <span style="font-size:18px;">class Apple  
  2. {  
  3.     String name;  
  4.     String color;  
  5.     boolean flag = false;  
  6. }  
  7. class Input implements Runnable  
  8. {  
  9.     private Apple r ;  
  10.     Input(Apple r)  
  11.     {  
  12.         this.r = r;  
  13.     }  
  14.     public void run()  
  15.     {  
  16.         int x = 0;  
  17.         while(true)  
  18.         {  
  19.             synchronized(r)  
  20.             {  
  21.   
  22.                 if(r.flag) //标志位,如果flag=true,那么说明已经有数据,线程等待  
  23.                     try{r.wait();}catch(Exception e){}  
  24.                 if(x==0)  
  25.                 {  
  26.                     r.name="a";  
  27.                     r.color="red";  
  28.                 }  
  29.                 else  
  30.                 {  
  31.                     r.name="b";  
  32.                     r.color = "yellow";  
  33.                 }  
  34.                 x = (x+1)%2;  
  35.                 r.flag = true;//修改标志位  
  36.                 r.notify();//唤醒输出线程  
  37.             }  
  38.         }  
  39.     }  
  40. }  
  41.   
  42. class Output implements Runnable  
  43. {  
  44.     private Apple r ;  
  45.       
  46.     Output(Apple r)  
  47.     {  
  48.         this.r = r;  
  49.     }  
  50.     public void run()  
  51.     {  
  52.         while(true)  
  53.         {  
  54.             synchronized(r)  
  55.             {  
  56.                 if(!r.flag)//如果线程的标志位flag=false,线程等待  
  57.                     try{r.wait();}catch(Exception e){}  
  58.                 System.out.println(r.name+"...."+r.color);  
  59.                 r.flag = false;  
  60.                 r.notify();//唤醒输入线程  
  61.             }  
  62.         }  
  63.     }  
  64. }  
  65. class  InputOutputTest  
  66. {  
  67.     public static void main(String[] args)  
  68.     {  
  69.         Apple r = new Apple();  
  70.   
  71.         Input in = new Input(r);  
  72.         Output out = new Output(r);  
  73.   
  74.         Thread t1 = new Thread(in);  
  75.         Thread t2 = new Thread(out);  
  76.   
  77.         t1.start();  
  78.         t2.start();  
  79.     }  
  80. }</span>  

总结:

      wait();notify();notifyALL();

      都使用在同步中,因为只有对持有监视器(锁)的线程操作。所以要使用在同步中个,因为只有同步才具有锁

为什么这些操作线程饿方法要定义Object类中呢?因为这些方法在操作同步线程时,都必须要标识他们所操作的线程只有的锁。只有在同一个锁上的被等待线程,可以被同一个锁notify唤醒。不可以对不同锁中的线程进行唤醒。也就说,等待和唤醒必须是同一个锁。而锁可以使任意对象个,所以可以被任意对象调用的方法定义object类中。

       终止线程只有一种,run方法结束。开启多线程运行,运行代码通常是循环结构。只要控制住循环,就可以让run方法结束,也就是线程结束。特殊情况:当线程处于了冻结状态。就不会读取到标记。那么线程就不会结束。当没有指定的方式让冻结的线程恢复到运行状态是,这时需要对冻结进行清除。强制让线程恢复到运行状态中来。这样就可以操作标记让线程结束。Thread类提供该方法 interrupt();

四、关于run()和start()分析:

[java]  view plaincopy
  1. <span style="font-size:18px;">class MyThread extends Thread{  
  2.     public void run(){  
  3.         try {  
  4.             Thread.currentThread().sleep(3000);  
  5.         } catch (InterruptedException e) {  
  6.         }  
  7.         System.out.println("MyThread running");  
  8.     }  
  9. }  
  10. public class ThreadTest{  
  11.     public static void main(String argv[]) {  
  12.         MyThread t = new MyThread();  
  13.         t.run();  
  14.         t.start();  
  15.         System.out.println("Thread Test");  
  16.       }  
  17. }</span>  

总结:

代码分析过程:MyThread t = new MyThread();创建了一个线程。

t.run();调用MyThread对象的run方法。这是只有一个线程在运行就是主线程。当主线程执行到了run方法中的sleep(3000);时。这是主线程处于冻结状态。程序并没有任何执行。当3秒过后,主线程打印了  MyThread running。 run方法执行结束。

t.start();开启了t线程。有两种可能情况。

       第一种,主线程在只执行了t.start()后,还具有执行权,继续往下执行,打印了Thread Test。主线程结束。

t线程获取执行权,调用自己的run方法。然后执行的sleep(3000);冻结3秒。3秒后,打印MyThread running t线程结束,整个程序结束。

      第二种,主线程执行到t.start();开启了t线程,t线程就直接获取到了执行权。就调用自己的run方法。指定到sleep(3000).t线程冻结3秒,这是t线程就是释放了执行权。那么主线程开始执行打印了Thread Test,主线程结束。

等到3秒后,t线程打印MyThread running ,然后t线程结束。程序结束。

目录
相关文章
|
11月前
|
设计模式 消息中间件 安全
【JUC】(3)常见的设计模式概念分析与多把锁使用场景!!理解线程状态转换条件!带你深入JUC!!文章全程笔记干货!!
JUC专栏第三篇,带你继续深入JUC! 本篇文章涵盖内容:保护性暂停、生产者与消费者、Park&unPark、线程转换条件、多把锁情况分析、可重入锁、顺序控制 笔记共享!!文章全程干货!
535 1
|
11月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
588 1
|
11月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
515 1
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
519 0
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
691 16
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
579 83
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
557 0