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

    1.1进程与线程

    1.2Java的多线程实现

      在java中要想实现多线程可以用以下两种方式

        继承Thread类

        实现Runnable接口

    1.2.1Thread类

      java.lang包会在程序运行时自动导入,所以不用手动编写import语句。

      一个类继承了Thread类之后,那么此类就具有了多线程的操作功能。

    class MyThread implements Runnable{    // 实现Runnable接口,作为线程的实现类
        private String name ;        // 表示线程的名称
        public MyThread(String name){
            this.name = name ;        // 通过构造方法配置name属性
        }
        public void run(){    // 覆写run()方法,作为线程 的操作主体
            for(int i=0;i<10;i++){
                System.out.println(name + "运行,i = " + i) ;
            }
        }
    };
    View Code

      以上已经完成了一个线程的操作类,直接使用此类就可以完成功能。

      以上的程序是先执行完A之后再执行B线程,并没有达到所谓的并发执行的效果。

      因为以上的程序实际上还是按古老的形式,通过对象方法去调用,但是如果想要启动一个线程必须使用Thread类中定义的start()方法。

      一旦调用start()方法,实际上最终调用的就是run()方法。

    class MyThread extends Thread{    // 继承Thread类,作为线程的实现类
        private String name ;        // 表示线程的名称
        public MyThread(String name){
            this.name = name ;        // 通过构造方法配置name属性
        }
        public void run(){    // 覆写run()方法,作为线程 的操作主体
            for(int i=0;i<10;i++){
                System.out.println(name + "运行,i = " + i) ;
            }
        }
    };
    public class ThreadDemo02{
        public static void main(String args[]){
            MyThread mt1 = new MyThread("线程A ") ;     // 实例化对象
            MyThread mt2 = new MyThread("线程B ") ;     // 实例化对象
            mt1.start() ;    // 调用线程主体
            mt2.start() ;    // 调用线程主体
        }
    };
    View Code

       从此处的效果来看,确实是并发执行的,那个线程先抢到了CPU资源,那个线程就执行。

    问题:

      为什么不直接调用run()方法,而是通过strat()调用呢?

      如果要解决这样的难题,则要打开Thread类的定义,在JDK的src.zip中全部都是JAVA的原程序代码,直接找到java.lang.Thread类,就可以打开Thread类的定义。

    class MyThread extends Thread{    // 继承Thread类,作为线程的实现类
        private String name ;        // 表示线程的名称
        public MyThread(String name){
            this.name = name ;        // 通过构造方法配置name属性
        }
        public void run(){    // 覆写run()方法,作为线程 的操作主体
            for(int i=0;i<10;i++){
                System.out.println(name + "运行,i = " + i) ;
            }
        }
    };
    public class ThreadDemo03{
        public static void main(String args[]){
            MyThread mt1 = new MyThread("线程A ") ;     // 实例化对象
            mt1.start() ;    // 调用线程主体
            mt1.start() ;    // 错误
        }
    };
    View Code

    1.2.2Runnable接口

    class MyThread implements Runnable{      // 实现Runnable接口,作为线程的实现类
      private String name ;                            // 表示线程的名称
      public MyThread(String name){
        this.name = name ;                       // 通过构造方法配置name属性
      }
      public void run(){ // 覆写run()方法,作为线程 的操作主体
        for(int i=0;i<10;i++){
          System.out.println(name + "运行,i = " + i) ;
        }
      }
    };

      如果要想启动线程则肯定依靠Thread类,但是之前如果直接继承了Thread类,则可以将start()方法直接继承下来并使用,但是Runnable接口中并没有此方法。

    Thread类的构造:

    public Thread(Runnable target)

      就利用以上的构造方法,启动多线程。

    class MyThread implements Runnable{    // 实现Runnable接口,作为线程的实现类
        private String name ;        // 表示线程的名称
        public MyThread(String name){
            this.name = name ;        // 通过构造方法配置name属性
        }
        public void run(){    // 覆写run()方法,作为线程 的操作主体
            for(int i=0;i<10;i++){
                System.out.println(name + "运行,i = " + i) ;
            }
        }
    };
    public class RunnableDemo01{
        public static void main(String args[]){
            MyThread mt1 = new MyThread("线程A ") ;     // 实例化对象
            MyThread mt2 = new MyThread("线程B ") ;     // 实例化对象
            Thread t1 = new Thread(mt1);
            Thread t2 = new Thread(mt2);             // 实例化Thread类对象
            t1.start();
            t2.start();
        }
    };
    View Code

      从运行效果可以发现,已经完成了多线程的功能。

    1.3Thread类与Runnable接口

    1.3.1Thread类与Runnable接口的联系

    Thread定义:

    public class Thread

    extends Object

    implements Runnable

      从定义格式上可以发现,Thread类也是Runnable接口的子类。

      从类的关系上来看,之前的做法非常类似于代理设计模式,Thread类完成比线程主体更多的操作。例如:分配CPU资源,判断是否已经启动等。

    1.3.2Thread类与Runnable接口的区别

      使用Thread类在操作多线程的时候无法达到资源共享的目的,而使用Runnable接口实现的多线程操作可以实现资源共享。

    class MyThread extends Thread{    // 继承Thread类,作为线程的实现类
        private int ticket = 5 ;        // 表示一共有5张票
        public void run(){    // 覆写run()方法,作为线程 的操作主体
            for(int i=0;i<100;i++){
                if(this.ticket>0){
                    System.out.println("卖票:ticket = " + ticket--) ;
                }
            }
        }
    };
    public class ThreadDemo04{
        public static void main(String args[]){
            MyThread mt1 = new MyThread() ;     // 实例化对象
            MyThread mt2 = new MyThread() ;     // 实例化对象
            MyThread mt3 = new MyThread() ;     // 实例化对象
            mt1.run() ;    // 调用线程主体
            mt2.run() ;    // 调用线程主体
            mt3.run() ;    // 调用线程主体
        }
    };
    View Code

        发现一共卖了15张票,证明了三个线程各自卖各自的5张票,也就是说现在并没有达到资源共享的目的。

      因为在每一个MyThread对象中都包含各自的ticket属性。

      如果现在使用Runnable接口呢?同样启动多个线程,那么所有的线程将卖出共同的5张票。

    class MyThread implements Runnable{    // 继承Thread类,作为线程的实现类
        private int ticket = 5 ;        // 表示一共有5张票
        public void run(){    // 覆写run()方法,作为线程 的操作主体
            for(int i=0;i<100;i++){
                if(this.ticket>0){
                    System.out.println("卖票:ticket = " + ticket--) ;
                }
            }
        }
    };
    public class RunnableDemo02{
        public static void main(String args[]){
            MyThread mt = new MyThread() ;     // 实例化对象
            new Thread(mt).run() ;    // 调用线程主体
            new Thread(mt).run() ;    // 调用线程主体
            new Thread(mt).run() ;    // 调用线程主体
        }
    };
    View Code

      从运行效果来看,现在启动了三个线程,但三个线程一共才卖了5张票。所以达到了资源共享的目的。

    1.3.3Thread类与Runnable接口的使用结论

    1.4线程的状态

     

      实际上,线程调用start()方法的时候不是立刻启动的,而是要等待CPU进行调度。

    2、总结

  • 相关阅读:
    vsphere平台windows虚拟机克隆的小插曲(无法登陆系统)
    mysql破解root用户密码总结
    mysql查询缓存参数
    mysql字符乱码
    做为一名dba你应该知道这些数据恢复
    mysql小技巧
    使用explain查看mysql查询执行计划
    mysql语句 索引操作
    mysqlbinglog基于即时点还原
    数据结构和算法(3)-向量,列表与序列
  • 原文地址:https://www.cnblogs.com/jerry201907/p/11239893.html
Copyright © 2011-2022 走看看