zoukankan      html  css  js  c++  java
  • Java多线程入门

    进程与线程

    在学习Java多线程之前,先简单复习一下进程与线程的知识。

    进程:进程是系统进行资源分配和调度的基本单位,可以将进程理解为一个正在执行的程序,比如一款游戏。

    线程:线程是程序执行的最小单位,一个进程可由一个或多个线程组成,在一款运行的游戏中通常会有界面更新线程、游戏逻辑线程等,线程切换的开销远小于进程切换的开销。

    在上图中,蓝色框表示进程,黄色框表示线程。进程拥有代码、数据等资源,这些资源是共享的,3个线程都可

    以访问,同时每个线程又拥有私有的栈空间。

    Java线程状态图

     线程的五种状态:

      1)新建状态(New):线程对象实例化后就进入了新建状态。

      2)就绪状态(Runnable):线程对象实例化后,其他线程调用了该对象的start()方法,虚拟机便会启

         动该线程,处于就绪状态的线程随时可能被调度执行。

      3)运行状态(Running):线程获得了时间片,开始执行。只能从就绪状态进入运行状态。

      4)阻塞状态(Blocked):线程因为某个原因暂停执行,并让出CPU的使用权后便进入了阻塞状态。

         等待阻塞:调用运行线程的wait()方法,虚拟机会把该线程放入等待池。

         同步阻塞:运行线程获取对象的同步锁时,该锁已被其他线程获得,虚拟机会把该线程放入锁定池。

         其他线程:调用运行线程的sleep()方法或join()方法,或线程发出I/O请求时,进入阻塞状态。

      5)结束状态(Dead):线程正常执行完或异常退出时,进入了结束状态。

    Java语言提供了两种实现线程的方式:

    1)通过继承Thread类实现线程

    public class ThreadTest {
    public static void main(String[] args){
    Thread thread = new MyThread(); //创建线程
    Thread thread1 = new MyThread();//创建线程1
    thread.start();//启动线程
    thread1.start();//启动线程1
    }
    }
    //继承Thread类
    class MyThread extends Thread{
    @Override
    public void run() {
    int count = 7;
    while(count>0){
    System.out.println(count);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    count--;
    }
    }
    }

    程序截图:

    2)通过实现Runnable接口实现线程

    
    
    public class ThreadTest {
    public static void main(String[] args){
    Runnable runnable = new MyThread();
    //将Runnable对象传递给Thread构造器
    new Thread(runnable).start();
    new Thread(runnable).start();
    }
    }
    //实现了Runnable接口
    class MyThread implements Runnable{
    @Override
    public void run() {
    int count = 7;
    while(count>0){
    System.out.println(count);
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    count--;
    }
    }
    }
     

     程序截图:

      两种方式都覆写了run()方法,run()方法内定义了线程的执行内容,我们只能通过线程的start()方法启动线程,且start()方法只能调用一次,当线程进入执行状态时,虚拟机会回调线程的run()方法。接调用线程的run()方法,并不会启动线程,只会像普通方法一样去执行。其实,Thread类本身也实现了Runnable接口。这两种方式都可以实现线程,但Java语言只支持单继承,如果扩展了Thread类就无法再扩展其他类,远没有实现接口灵活。

    常用方法

    1)Thread类

      Thread():用于构造一个新的Thread。

      Thread(Runnable target):用于构造一个新的Thread,该线程使用了指定target的run方法。

      Thread(ThreadGroup group,Runnable target):用于在指定的线程组中构造一个新的Thread,该

      线程使用了指定target的run方法。

      currentThread():获得当前运行线程的对象引用。

      interrupt():将当前线程置为中断状态。

      sleep(long millis):使当前运行的线程进入睡眠状态,睡眠时间至少为指定毫秒数。

      join():等待这个线程结束,即在一个线程中调用other.join(),将等待other线程结束后才继续本线程。

      yield():当前执行的线程让出CPU的使用权,从运行状态进入就绪状态,让其他就绪线程执行。

    2)Object类

      wait():让当前线程进入等待阻塞状态,直到其他线程调用了此对象的notify()或notifyAll()方法后,

      前线程才被唤醒进入就绪状态。

      notify():唤醒在此对象监控器上等待的单个线程。

      notifyAll():唤醒在此对象监控器上等待的所以线程。

           注:wait()、notify()、notifyAll()都依赖于同步锁,而同步锁是对象持有的,且每个对象只有一个,所以这些方法定义在Object类中,而不是Thread类中。

    3)yield()、sleep()、wait()比较

       wait():让线程从运行状态进入等待阻塞状态,并且会释放它所持有的同步锁。

       yield():让线程从运行状态进入就绪状态,不会释放它锁持有的同步锁。

       sleep():让线程从运行状态进入阻塞状态,不会释放它锁持有的同步锁。

  • 相关阅读:
    Gradle更小、更快构建APP的奇淫技巧
    一篇文章让你了解Android各个版本的历程
    快速开发android,离不开这10个优秀的开源项目
    .net 使用AjaxControlToolkit.dll 遇到的"Sys"未定义问题
    ajax xmlhttp下open方法POST、GET参数的区别
    ArrayList 类和List<T>泛型类
    LINQ to SQL
    StudioStyle 使用 厌倦了默认的Visutal Studio样式了,到这里找一个酷的试试
    C#中byte[]与string的转换
    c#中的interface abstract与virtual
  • 原文地址:https://www.cnblogs.com/1iHu4D0n9/p/9023413.html
Copyright © 2011-2022 走看看