JAVA复习笔记之多线程(1)

2.多线程的作用:提高CPU的利用率(进程之间的内存是相互独立的,看似是多个进程一起执行,实际上是计算机处理速度比较快,进程之间一直在快速的切换着)。
3. 线程是进程的执行场景,一个进程可以启动多个线程,这多个线程共享进程的内存和资源。
4.进程引入多线程的作用: 提高进程的使用率(线程之间的栈内存相互独立,堆内存和方法区内存共享。即:一个线程就是一个栈)。
5.JAVA程序的运行原理:通过java命令调用JVM,JVM的启动表示了一个应用的启动(进程的启动),
这个进程会自动启动一个主线程,这个主线程会调用一个类的main方法,通过main方法可以执行其他的分支线程,如果在执行其他分支线程的时候main方法已经结束,程序不一定结束(因为可能有其他的分支线程在执行,main方法结束后虽然栈空了,但是线程之间的栈是独立的,所以可以执行其他分支)。
6.在JAVA的多线程:
(1)继承方法Thread,样例代码:

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Test2 test = new Test2();
        test.start();//Test2.run();
        Test3();
    }
    public static void Test3(){
    
    
        for (int i=100; i<=1000; i++){
    
    
            System.out.println(i);
        }
    }
}
class Test2 extends Thread{
    
    
   public  void run (){
    
    
       for(int i=1; i<=100; i++){
    
    
           System.out.println(i);
       }
   }

如果不按照多线程来看,想要执行另一个类中的方法,需要 (类名.方法名)来调用。这个时候方法的执行是按照顺序来有序执行的。假设上面代码没有使用多线程,则会先执行Test2中的方法,输出1-100,再执行Test3中的方法输出100-1000.
如果按照多线程来看,首先让一个类来继承Thread方法,然后需要重写Thread中的run方法,来覆盖掉父类的run方法。在主线程中来new一个Test2的对象,通过start来启动线程(这里不需要在主动调用run方法,start会使该线程进入就绪状态,然后通过java线程调度机制来完成),此时在控制板上的输出则是“串插”着输出的。
(2)实现接口Runnable,样例代码:

    public class Test extends Thread{
    
    
    public static void main(String[] args) {
    
    
      Thread test = new Thread(new Test3());
      test.start();
      Test2();
    }
    public static void Test2(){
    
    
        for (int i=200; i<=300; i++){
    
    
            System.out.println(i);
        }
    }
}
class Test3 implements Runnable{
    
    
    public  void run(){
    
    
        for(int i=1; i<=100; i++){
    
    
            System.out.println(i);
        }
    }
}

实现接口来完成多线程,是现在类中new一个另一个类的对象(想要启动的分支线程),然后再使用Thread,再new一个对象,将刚刚的对象当做参数传入,再通过start来启动。想比较继承Thread来说,实现Runnable更好,因为JAVA中只能单继承,接口可以实现多个。
7.线程的生命周期:
新建:成功 new 一个对象。
就绪:start 的执行
执行:JVM的调度
阻塞:IO设备的请求,Sleep, Wait 语句的使用等
终止:线程执行完毕(run方法结束)。
8.线程的调度:
分时调度:每个线程平均分配占用CPU的时间
优先级调度:优先级越高,分配的CPU的时间越长。(抢占式调度)
9. 线程的优先级分为:MAX_PRIORITY(高级),MIN_PRIORITY(低级),NOM_PRIORITY(中级)例:

    public class Test {
    
    
    public static void main(String[] args) {
    
    
        Thread test = new Thread(new Test2());
        Thread test2 = new Thread(new Test4());
        test.setPriority(Thread.MAX_PRIORITY);//设置最高优先级
       test2.setPriority(Thread.MIN_PRIORITY);//设置最低优先级
        test.start();
        test2.start();
    }
}
class  Test2 implements Runnable{
    
    
    public void run(){
    
    
        for (int i=1; i<99; i++){
    
    
            System.out.println(i);
        }
    }

}
class  Test4 implements Runnable{
    
    
    public void run(){
    
    
        for (int i=99; i<199; i++){
    
    
            System.out.println(i);
        }
    }
}

优先级越高分配的时间片大概率的越多,所以在以上代码中,Test2比Test4提前完成的几率是很大的(线程启动后不能再设置优先级)
10.线程的睡眠:
sleep:单位为毫秒,作用是让当前的线程休眠多少时间(进入阻塞状态,将占用CPU的时间片给别的线程,睡眠时间结束后接着运行)。例:

  public class Test {
    
    
    public static void main(String[] args) {
    
    
         new Thread(new Test2()).start();
    }
}
class  Test2 implements Runnable{
    
    
    public void run(){
    
    
        try {
    
    
            System.out.println("休眠5秒");
            //sleep需抛出InterruptedException异常
            //且Thread.sleep在哪个代码块中,就只能休眠
            //这个代码块
            Thread.sleep(5*1000);
            for(int i=1; i<=100; i++){
    
    
                System.out.println(i);
            }
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }
}

11.线程的让位:
Thread.yield()方法不是阻塞方法。让当前线程让位,让给其它线程
(让位给同级的线程) 使用。yield()方法的执行会让当前线程从“运行状
态”回到“就绪状态”,进入就绪后,会接着抢夺时间片。
12.线程的合并:
Test(线程对象).join,将Test线程合并到当前join所在线程,阻塞当前join所在的线程,执行Test线程。(只是线程合并,栈并没有合并)。
13.线程的中断(结束sleep睡眠):
Test(线程对象).interrupt,使sleep抛出异常,从而结束sleep的休眠。

猜你喜欢

转载自blog.csdn.net/Badman0726/article/details/118797526