• java多线程_01_线程的基本概念


    线程:一个程序里边不同的执行路径

    例子程序:这个例子程序是一条执行路径。这个程序只有一个分支,就是main方法,叫主线程

    public static void main(String[] args) {
            m1();
        }
        public static void m1(){
            m2();
            m3();
        }
        public static void m2(){}
        public static void m3(){}

    程序执行示意图:

    进程:进程是一个静态的概念,机器上的一个class文件,一个exe文件。

    程序的执行过程,要把程序的代码放到内存里,放到代码区里,一个进程准备开始,进程已经产生了,但还没有开始执行,这叫进程。是一个静态的概念。平时说的进程的执行说的是进程里面主线程开始执行了。在机器里面运行的实际上都是线程。 

    我们的windows同时运行着好多个线程,所以说机器是支持多线程的。当然也支持多进程。windows、linux、unix都是多进程、多线程的,dos是只支持单进程的,同一个时间点只能执行一个进程执行。

    CPU计算速度快,把自己的时间分成一个个时间片,这个时间片执行你一会,下一个时间片执行它一会,轮着来。虽然有几十个线程,轮着执行由于速度很快,在我们看来就像是多个线程同时执行的。但实际上,一个时间点上,CUP只有一个线程在运行。(如果机器是多核,有多个CPU,才是真正意义上的多线程)

    实现Runnable接口:

    package thread;
    
    public class TestThread01 {
        public static void main(String[] args) {
            Runner1 r = new Runner1();
            Thread t = new Thread(r);
            t.start();//启动线程,通知CPU线程已经准备好了,有空了来执行我一会
            
            for (int i = 0; i < 100; i++) {
                System.out.println("------Main Thread: "+i);
            }
        }
    }
    class Runner1 implements Runnable{
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println("Runner1 : "+i);
            }
        }
    }

    执行结果:轮着执行

     继承Thread类:

    package thread;
    
    public class TestThread01 {
        public static void main(String[] args) {
            
            Runner1 r = new Runner1();
            r.start();//本身就是Thread,直接调用start
    //        Thread t = new Thread(r);
    //        t.start();//启动线程,通知CPU线程已经准备好了,有空了来执行我一会
            
            for (int i = 0; i < 100; i++) {
                System.out.println("------Main Thread: "+i);
            }
        }
    }
    //class Runner1 implements Runnable{
    class Runner1 extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println("Runner1 : "+i);
            }
        }
    }

    能实现接口就不继承Thread类。

    线程的状态转换:

     

    一个线程类,new出来只是内存里的一个对象。调用start方法,不是立即执行,而是就绪状态,排队等候,因为CPU可能正在执行其他的线程。CPU高兴了,把对象调到CPU里才得以执行。执行的过程中,可能你的时间片到头了,还回到就绪状态去排队去,等候下次轮到你,一直到执行完了,就终止了。

    运行过程中,可能有情况发生了,你必须要等到情况解决了才能继续运行,这叫阻塞状态。

    优先级越高的线程,获得的CPU执行的时间越多。

     

    Sleep:

    package thread;
    
    import java.util.*;
    
    public class TestInterrupt {
        public static void main(String[] args) {
            MyThread thread = new MyThread();
            thread.start();//啟動線程
            try {
                //主線程睡10秒,執行MyThread,打印10個時間
                Thread.sleep(10000);
            } catch (InterruptedException e) {
            }
            //打印10个时间后执行到此,调用interrupt方法中断线程。
            thread.interrupt();
        }
    }
    
    class MyThread extends Thread {
        boolean flag = true;
        public void run() {
            while (flag) {
                System.out.println("===" + new Date() + "===");
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    return;
                }
            }
        }
    }

    结果:打印10个时间后,线程结束 。     Run方法一结束,线程就结束了

    ===Mon Jun 26 22:19:40 CST 2017===
    ===Mon Jun 26 22:19:41 CST 2017===
    ===Mon Jun 26 22:19:42 CST 2017===
    ===Mon Jun 26 22:19:43 CST 2017===
    ===Mon Jun 26 22:19:44 CST 2017===
    ===Mon Jun 26 22:19:45 CST 2017===
    ===Mon Jun 26 22:19:46 CST 2017===
    ===Mon Jun 26 22:19:47 CST 2017===
    ===Mon Jun 26 22:19:48 CST 2017===
    ===Mon Jun 26 22:19:49 CST 2017===

     Join:合并某个线程,(等待该线程终止)

    代码:

    package thread;
    
    public class TestJoin {
      public static void main(String[] args) {
        MyThread2 t1 = new MyThread2("abcde");
        t1.start();
        try {
            /**
             * 把t1线程合并到主线程,即等待t1线程执行完,再执行主线程
             * 相当于方法调用
             */
            t1.join();
        } catch (InterruptedException e) {}
        //等t1执行完了,才有机会执行这
        for(int i=1;i<=10;i++){
          System.out.println("i am main thread");
        }
      }
    }
    class MyThread2 extends Thread {
      MyThread2(String s){//给线程起名字
          super(s);
      }
      
      public void run(){
        for(int i =1;i<=10;i++){
          System.out.println("i am "+getName());
          try {
              sleep(1000);
          } catch (InterruptedException e) {
              return;
          }
        }
      }
    }

    join把t1合并到主线程,main会等待着t1执行完,再执行自己。

    结果:

    i am abcde
    i am abcde
    i am abcde
    i am abcde
    i am abcde
    i am abcde
    i am abcde
    i am abcde
    i am abcde
    i am abcde
    i am main thread
    i am main thread
    i am main thread
    i am main thread
    i am main thread
    i am main thread
    i am main thread
    i am main thread
    i am main thread
    i am main thread

    Yield:

    package thread;
    
    public class TestYield {
      public static void main(String[] args) {
        MyThread3 t1 = new MyThread3("------t1");
        MyThread3 t2 = new MyThread3("t2");
        t1.start();
        t2.start();
      }
    }
    class MyThread3 extends Thread {
      MyThread3(String s){super(s);}
      public void run(){
        for(int i =1;i<=100;i++){
          System.out.println(getName()+": "+i);
          if(i%10==0){//能被10整除,让出时间片,不明显
            yield();
          }
        }
      }
    }

    结果:应该每到整除10,就让给其他线程,但是不明显。

    ------t1: 1
    ------t1: 2
    ------t1: 3
    ------t1: 4
    ------t1: 5
    ------t1: 6
    ------t1: 7
    ------t1: 8
    ------t1: 9
    ------t1: 10
    t2: 1
    t2: 2
    t2: 3
    t2: 4
    t2: 5
    t2: 6
    ------t1: 11

    。。。。。

    线程的优先级:

    package thread;
    
    public class TestPriority {
        public static void main(String[] args) {
            Thread t1 = new Thread(new T1());
            Thread t2 = new Thread(new T2());
            t1.setPriority(Thread.NORM_PRIORITY + 3);
            t1.start();
            t2.start();
        }
    }
    
    class T1 implements Runnable {
        public void run() {
            for(int i=0; i<1000; i++) {
                System.out.println("T1: " + i);
            }
        }
    }
    
    class T2 implements Runnable {
        public void run() {
            for(int i=0; i<1000; i++) {
                System.out.println("------T2: " + i);
            }
        }
    }

    结果:不明显

    T1: 0
    T1: 1
    T1: 2
    T1: 3
    T1: 4
    T1: 5
    T1: 6
    T1: 7
    T1: 8
    T1: 9
    T1: 10
    T1: 11
    T1: 12
    T1: 13
    T1: 14
    T1: 15
    T1: 16
    T1: 17
    T1: 18
    T1: 19
    T1: 20
    T1: 21
    T1: 22
    T1: 23
    T1: 24
    T1: 25
    T1: 26
    T1: 27
    T1: 28
    T1: 29
    T1: 30
    T1: 31
    T1: 32
    T1: 33
    T1: 34
    T1: 35
    T1: 36
    T1: 37
    T1: 38
    T1: 39
    T1: 40
    T1: 41
    T1: 42
    T1: 43
    T1: 44
    T1: 45
    T1: 46
    T1: 47
    T1: 48
    T1: 49
    T1: 50
    T1: 51
    T1: 52
    T1: 53
    T1: 54
    T1: 55
    T1: 56
    T1: 57
    T1: 58
    T1: 59
    T1: 60
    T1: 61
    T1: 62
    T1: 63
    T1: 64
    T1: 65
    T1: 66
    T1: 67
    T1: 68
    T1: 69
    T1: 70
    T1: 71
    T1: 72
    T1: 73
    T1: 74
    T1: 75
    T1: 76
    T1: 77
    T1: 78
    T1: 79
    T1: 80
    T1: 81
    T1: 82
    T1: 83
    T1: 84
    T1: 85
    T1: 86
    T1: 87
    T1: 88
    T1: 89
    T1: 90
    T1: 91
    T1: 92
    T1: 93
    T1: 94
    T1: 95
    T1: 96
    T1: 97
    T1: 98
    T1: 99
    T1: 100
    T1: 101
    T1: 102
    T1: 103
    T1: 104
    T1: 105
    T1: 106
    T1: 107
    T1: 108
    T1: 109
    T1: 110
    ------T2: 0
    T1: 111
    ------T2: 1
    T1: 112
    ------T2: 2
    T1: 113
    ------T2: 3
    T1: 114

  • 相关阅读:
    js实现可配置参数的轮播图
    js获取、修改CSS样式
    js值的类型和函数传参
    DOM事件
    C主函数:void main(int argc,char *argv[] )
    eclispe无法获取maven依赖的本地项目jar包
    eclipse没有server选项解决方法
    Eclipse中Tomcat的add and remove找不到项目
    java简单web爬虫(网页图片)
    (转)大前端完整学习路线(详解)
  • 原文地址:https://www.cnblogs.com/lihaoyang/p/7082439.html
Copyright © 2020-2023  润新知