• java线程学习


    一、线程的创建

      java中创建线程有两种方式:继承Thread类和实现Runnable接口。

      1.继承Thread类

      Java语言中定义了线程类Thread,用户可以通过继承Thread类,覆盖其run()方法创建自己的线程类,线程执行的代码都包含在run方法中。

      public ClassName extends Thread{

        public void run(){

        }

      }

      2.实现Runnable接口

      另一种线程的实现方式是实现Runnable接口。如果自定义的线程还要继承其他类,这时就不能采用第一种方式来创建,java语言是不支持多继承的,却可以实现多个接口,线程同样要实现Runnable接口中的run方法,线程需要执行的代码都包含在run方法中。

      Class MyThread implements Runnable{

        public void run(){

        }

      }

    二、线程的启动

      继承Thread类方式的线程启动非常简单,只要创建线程类实例后调用其start()方法用来完成线程的启动。

      ClassName c = new ClassName();

      c.start();

      实现Runnable接口创建的线程首先转换为Thread类,然后调用Thread类的start()方法启动线程。

      MyThread  mt = new MyThread();

      Thread t = new Thread(mt);

      t.start();

    三、线程的生命周期

      一个生命周期内的线程主要包括创建、就绪、运行、阻塞和死亡状态。

      1.创建:在线程类使用new关键字实例化之后在调用start()方法之前,线程处于创建状态。处于创建状态的线程仅仅分配了内存空间,属于生命周期的初始状态。

      2.就绪:在线程调用了start()方法后即处于就绪状态。处于就绪状态的线程具备了除CPU之外运行所需的所有资源。就绪状态线程排队等待CPU,由系统调度为其分配。

      3.运行:处于就绪状态的线程获得CPU之后即处于运行状态。处于运行状态的线程才开始正真执行线程run()方法的内容。

      4.阻塞:处于运行状态的线程如果因为某种原因不能继续执行,则进入阻塞状态。阻塞状态与就绪状态不同的是:就绪状态只是因为缺少CPU而不能执行,而阻塞状态是由于各种原因引起线程不能执行,不仅仅是缺少CPU。引起阻塞的原因解除之后,线程再次转化为就绪状态。

      5.死亡:当线程执行完run()方法的内容或被强制终止时,线程处于死亡状态,整个生命周期结束。

    四、线程的调度

      1.线程的优先级:在java语言中,通过调用setPriority()方法为线程设置优先级,优先级用1~10的数字表示,数字越大,优先级越高。如:c.setPriority(1),接着再启动线程。

      2.线程休眠:对于正在执行的线程,可以调用sleep()方法使其放弃CPU进行休眠,此线程转为阻塞状态,sleep()方法包含long型的参数,用于指定线程休眠的时间,单位为毫秒。

      3.线程让步:对于正在执行的线程,可以调用yield方法使其重新排队,将CPU让给排在后面的线程,此线程转为就绪状态。yield()方法只让步给高优先级或同等优先级的线程。

      4.线程等待:对于正在执行的线程,可以调用join()方法等待其结束,然后才执行其他程序。

        如:c.start();

          c.join();

          t.start;

      等待c线程执行完成再执行t.

    五、线程同步

      当多个线程操作同一个共享资源时,比如读写同一个变量,存在着资源竞争的问题。为了解决此类问题,需要使用同步机制。在java语言中,利用synchronized关键字实现线程同步。

      实例如下:

    class MyThread implements Runnable{
      private int con = 0;

      @Override
      public void run() {
        test();
      }
      private void test(){
        for(int i = 0;i<10;i++){
          con++;
          Thread.yield();
          con--;
          System.out.println(con);
        }
      }
    }

    public class testThread {
      public static void main(String[] args) {
        MyThread t = new MyThread();
        Thread t1 = new Thread(t);
        Thread t2= new Thread(t);

        t1.start();
        t2.start();
    }
    }

    结果如下:

    0
    0
    0
    0
    0
    0
    1
    0
    0
    1
    0
    1

    调整如下:

    class MyThread implements Runnable{
      private int con = 0;

      @Override
      public void run() {
        test();
      }
      private synchronized void test(){
        for(int i = 0;i<10;i++){
          con++;
          Thread.yield();
          con--;
          System.out.println(con);
        }
      }
    }

    public class testThread {
      public static void main(String[] args) {
        MyThread t = new MyThread();
        Thread t1 = new Thread(t);
        Thread t2= new Thread(t);

        t1.start();
        t2.start();
      }
    }

    输出的结果全为0.

  • 相关阅读:
    Mysql索引优化
    [ExtJS5学习笔记]第六节 Extjs的类系统Class System命名规则及定义和调试
    [ExtJS5学习笔记]第五节 使用fontawesome给你的extjs5应用增加字体图标
    【翻译】Ext JS 5.0.1 中的新功能
    OpenCV——PS图层混合算法(六)
    [IDE工具配置]myeclipse 2014 专业版 安装 svn插件
    OpenCV——PS 图层混合算法 (四)
    [ExtJS5学习笔记]第四节 欢迎来到extjs5-手把手教你实现你的第一个应用
    [ExtJS5学习笔记]第三节 sencha cmd学习笔记 生成应用程序构建的内部细节
    [ExtJS5学习笔记]第二节 Sencha Cmd 学习笔记 使你的sencha cmd跑起来
  • 原文地址:https://www.cnblogs.com/czl362326/p/5631604.html
Copyright © 2020-2023  润新知