Java线程相关概念及方法基本使用

Java学习-09-韩顺平老师

Java-线程入门01

线程相关概念及基本使用

线程的相关概念:

  • 进程
1.进程是指运行中的程序,比如我们使用qq,就会启动一个进程,操作系统就
  会为改进程分配内存空间,当我们使用迅雷的,又启动了一个进程,操作系统
  将为迅雷分配空间。
2.进程是程序的执行过程,或是正在运行的一个程序。是一个动态过程:有它自身
  的残生、存在和消亡的过程。
  • 线程
1.线程是进程创建的,是进程的一个实体。
2.一个进程可以右多个进程。
3.线程也可以载创建线程。
举例:当我们使用迅雷下载一个文件的时候,进程就会创建一个线程来下载,
    如果又有一个文件要用迅雷下载,那么迅雷就会在创建一个线程下载。
4.单线程:同一个时刻,只允许执行一个线程。
5.多线程:同一个时刻,可以执行多个线程,比如qq可以同时打开多个聊天窗口.
6.并发:同一时刻,多个任务交给一个CPU来交替执行,造成一种"貌似同时"的错觉,
       简单来说,单核Cpu实现多任务就是并发。
7.并行:同一时刻,多个任务由多个Cpu来执行,称为并行。

线程的基本使用

  • 创建线程的两种基本方式
    1.继承Thread类,重写run方法
public class ThreadWays {
    public static void main(String[] args) {
        Thread01 thread01 = new Thread01();
        Thread01 thread02 = new Thread01();
        thread01.start();
        thread02.start();
    }
}

class Thread01 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程" +Thread.currentThread() + "正在打印i = " + i);
            if (i == 8){
                break;
            }
        }
    }
}

   2.实现Runnable接口,并重写run方法

public class ThreadWays {
    public static void main(String[] args) {
        Thread01 thread01 = new Thread01();
        Thread01 thread02 = new Thread01();
        // 但是这里不能使用start来启动线程
        // 通过给Thread对象,传入一个 线程在调用start方法
        new Thread(thread01).start();
        new Thread(thread02).start();
    }
}

class Thread01 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程" +Thread.currentThread() + "正在打印i = " + i);
            if (i == 8){
                break;
            }
        }
    }
}

关于为什么线程调用start方法,而不是调用run方法:

1.调用start方法实际上底层是调用了start0() private native void start0();
  这个方法是原生方法,是由JVM机调用的,可以理解为,由JVM机来调用我们定义的
  run方法。
2.如果直接调用run方法,将不是创建线程来执行,会等run函数执行完,在执行其他代码。

线程终止:

1.当线程完成任务后,会自动退出。
2.还可以通过变量来控制run方法退出的方式俩停止线程,即通知方式。

线程的常用方法:

1.setName:设置线程名称
2.getName:返回线程的名称。
3.start:使该线程开始执行,Java虚拟机底层调用该线程的start0()方法。
4.run:调用线程对象的run 方法。
5.setPriority:设置线程的优先级。
6.getPriority:获取线程的优先级。
7.sleep:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。
8.interrupt:中断线程,不是退出线程。
9.yield:线程礼让,让出cpu,让其他线程执行,让的时间不确定,所以礼让不一定成功,
        当cpu空间充足的时候,一般都是礼让失败.
10.join:线程插队,插队的线程一旦插队成功,则肯定先执行完插入线程的任务,再回来
        当前线程的任务。

演示代码:

public class ThreadMethod {
    public static void main(String[] args) {
        Thread02 thread02 = new Thread02();
        thread02.setName("线程1");
        // Thread.MIN_PRIORITY  = 1
        // Thread.NORM_PRIORITY = 5
        // Thread.MAX_PRIORITY  = 10
        thread02.setPriority(Thread.MIN_PRIORITY);
        thread02.start();
    }
}

class Thread02 extends Thread{
    @Override
    public void run() {
        while (true){
            System.out.println(this.getName()); // 线程1
            System.out.println(this.getPriority()); // 1
            try {
                Thread.sleep(1000); // 休眠一秒钟
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            try {
                this.interrupt();// 中断当前线程,会进入下一个循环
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

join插队演示

public class YieldAndJoin {
    public static void main(String[] args) {
        Brother brother = new Brother();
        Thread thread = new Thread(brother);
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread() + "正在运行" + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(i == 5){ // 当i=5的时候,让brother线程插队
                try {
                    thread.start(); // 启动线程
                    thread.join(); // 采用join插队,一定成功,要等Brother线程执行完,才会回到主线程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class Brother implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread() + "正在运行" + i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

方法使用细节:

1.start底层会创建新的线程,调用run,run就是一个简单的方法调用,不会启动新的线程。
2.interupt 终端线程,但并没有真正的结束线程,所以一般用于中断正在休眠的线程。
3.sleep线程的静态方法,使当前线程休眠。

用户线程和线程守护

1.用户线程,也叫工作线程,当线程任务执行完或通知方式结束。
2.守护线程:一般为工作线程服务的,当所有用于线程结束,守护线程自动结束。
3.常见的守护线程:垃圾回收机制。
public class Daemon_ {
    public static void main(String[] args) {
        DaemonThread daemonThread = new DaemonThread();
        daemonThread.setDaemon(true); // 将daemonThread设置为守护线程
        daemonThread.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("主线程正在运行");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("主线程退出啦"); // 当输出主线程退出啦,守护线程就会立马退出。
    }
}

class DaemonThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("守护线程正在运行!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

线程学习基本概念及使用小结,欢迎大家交流学习!

你可能感兴趣的:(Java,java,开发语言,后端)