• [转]java多线程例子


    1.  代码实例

    这里我们做一个完整的例子来说明线程产生的方式不同而生成的线程的区别:

    package com.example.ThreadTestDemo;
    
    public class ThreadTest extends Thread {
      public static void main(String[] args) throws Exception{
        
        for(int i=0;i<10;i++){
          Thread t = new MyThread();
          t.start();
        }
        Thread.sleep(10000);    //让上面的线程运行完成
        R r = new R();
        for(int i=0;i<10;i++){
          Thread t = new Thread(r);
          t.start();
        }
      }
    }
    
    class MyThread extends Thread{
        public int x = 0;
    
        public void run(){
          System.out.println(++x);
        }
      }
    
      class R implements Runnable{
        private int x = 0;
        public void run(){
          System.out.println(++x);
        }
      }

    输出结果为:1 1 1 1 1 1 1 1 1 1 

                     1 2 5 4 3 8 10 7 6 9

    上面10个线程对象产生的10个线程运行时打印了10次1。下面10个线程对象产生的10个线程运行时打印了1到10。我们把下面的10个线程称为同一实例(Runnable实例)的多个线程

    2.  线程对象的几个重要方法

    1. start方法

         一个线程对象生成后,如果要产生一个执行的线程,就一定要调用它的start()方法。在介绍这个方法时不得不同时说明run方法。其实线程对象的run方法完全是一个接口回调方法,它是你这个线程对象要完成的具体逻辑。简单说,你要做什么你就在run方法中完成。而如何做,什么时候做就不需要你控制了,你只要调用start方法,JVM就会管理这个线程对象让它产生一个线程并注册到线程管理系统中。

        从表面上看,start()方法调用了run()方法,事实上并没有直接调用run方法。在JDK1.5以前start()方法是本地方法,它如何最终调用run方法已经不是JAVA程序员所能了解的。而在JDK1.5中,原来的那个本地start方法被start0()代替,另一个纯JAVA的start()中调用本地方法start0(),而在start()方法中做了一个验证,就是对一个全局变量(对象变量)started做检验,如果为true,则start()抛出异常,不会调用本地方法start0(),否则,现将该变量设为true,然后调用start0()。

        从中我们可以看到这个为了控制一个线程对象只能运行成功一次start()方法。这是因为线程的运行要获取当前环境,包括安全,父线程的权限,优先级等条件,如果一个线程可以运行多次,那么定义一个static的线程在一个环境中获取相应权限和优先级,运行完成后它在另一个环境中利用原来的权限和优先级等属性在当前环境中运行,这样就造成无法预知的结果。简单说,让一个线程对象只能成功运行一次,是基于对线程管理的需要。

        start()方法最本质的功能是从CPU中申请另一个线程空间来执行run方法中的代码,它和当前线程是两条线,在相对独立的线程空间运行。也就是说,如果你直接调用线程对象的run方法,当然也会执行,但那是在当前线程中执行,run方法执行完成后继续执行下面的代码。而调用start()方法后,run方法的代码会和当前线程并发(单CPU)或并行(多CPU)执行。

        所以请记住一句话:调用线程对象的run方法不会产生一个新的线程,虽然可以达到相同的执行结果,但执行过程和执行效率不同。

    2. sleep,join,yield方法

        先简单说一下这些方法的作用和调用原则。

  • 相关阅读:
    python基础之ATM-2
    python基础之ATM-1
    正则表达式之实战--计算器
    logging模块小知识--同时往不同文件写日志
    re模块详解
    logging模块详解
    hashlib模块
    xml处理模块
    C++ 类的成员函数指针 ( function/bind )
    DirectShow 最简单的入门 -- 播放一段视频
  • 原文地址:https://www.cnblogs.com/wangwenjin2026/p/4547535.html
Copyright © 2020-2023  润新知