Java-多线程

一、进程与线程

进程:是资源分配的最小单位,操作系统中一个程序开始执行就产生一个进程,是动态概念。

线程:是程序执行的最小单位,它是进程的一个执行流。一个程序执行多个任务,每个任务就是一个线程。

1、进程和线程的区别:

  • 线程更加“轻量级”,创建和关闭的开销小。
  • 没有进程就没有线程。
  • 每个进程拥有独立的内存空间,而线程之间共享数据,因此线程间通信比进程之间更加方便。

2、线程的状态:

5种状态:创建、就绪、阻塞、运行、结束。

二、java多线程的实现

线程的创建方式,有四种方式:继承Thread类,实现Runnable接口,实现Callable接口,还有一种方式就是线程池。

1、继承 Thread 类

  • 线程类只能单继承,不能再继承其它类(受限于Java类的继承)
  • 业务实现在 run() 方法中,业务和线程实现耦合
  • 业务是不能共享的

例子:继承 Thread 类实现多线程:

class MyThread extends Thread {
    private String name;
    public MyThread(String name){
        this.name = name;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(this.name + " " + i);
        }
    }
}

public class ThreadTest{
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread("Thread_1");
        MyThread myThread2 = new MyThread("Thread_2");
        myThread1.start();
        myThread2.start();
    }
}

注意:启动线程不能直接去调用 run() 方法,否则只是简单的方法调用,和多线程无关,应该使用 start() 方法启动多线程。总之,不管何种情况,多线程的启动只有使用 Thread 类中的 start() 方法。

2、实现 Runnable 接口

  • 解决单继承问题
  • 业务实现和线程实现解耦
  • 业务可以共享
  • 使用 Lambda 表达式和匿名内部类的方式创建 Runnable 对象(开发常用)
  • run() 方法的返回值是 void , 业务如果有返回值无法处理

例子:通过 Runnable 接口实现多线程

class MyThread implements Runnable {
    private String name;
    public MyThread(String name){
        this.name = name;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(this.name + " " + i);
        }
    }
}

public class ThreadTest{
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread("Thread_1");
        MyThread myThread2 = new MyThread("Thread_2");
        //Runnable接口中只有一个run()方法,没有start()方法
        //要启动多线程,只能通过Thread类的构造方法实现
        new Thread(myThread1).start();
        new Thread(myThread2).start();
    }
}

3、实现 Callable 接口

  • 可以处理返回结果
  • 使用 Callable 的业务对象,通过 FutureTask 来获取执行结果

例子:通过 Callable 接口实现多线程

class MyThread implements Callable<String> {
    private int ticket = 10;
    @Override
    public String call() throws Exception {
        while (this.ticket > 0) {
            this.ticket--;
            System.out.println("还剩" + " " + this.ticket + " " + "张票");
        }
        return "票卖完了!";
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        FutureTask<String> task = new FutureTask<>(new MyThread());
        new Thread(task).start();
        new Thread(task).start();
        try {
            System.out.println(task.get());//打印最后的结果
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }
}

4、线程池:(后面补充)

思考:Thread 和 Runnable 的区别:

  • Runnable 可以多继承,没有继承局限性。
  • Thread 类是 Runnable 接口的子类
  • 多线程的处理使用的是代理设计模式
  • 使用 Runnable 实现的多线程程序类可以更好地描述出程序共享的概念

三、多线程的常用操作方法

1、线程命名与获取

要设置和取得线程的名字,就必须取得当前线程的对象,可以使用Thread类中的方法:

public static native Thread currentThread();

构造方法:public Thread(Runnable target,String name) 

设置线程的名字:public final synchronized void setName(String name) 

取得线程名字:public final String getName() 

主方法本身就是一个线程,所有的线程都是通过主方法创建并启动的。

2、线程休眠(sleep)

Thread.sleep()

  1. 线程暂停执行,进入阻塞状态

  2. 交出CPU

  3. 不释放占用的资源锁

  4. 休眠时间到了回到就绪状态

3、线程让步(yield)

Thread.yield()

  1. 线程暂停执行,进入就绪状态

  2. 交出CPU,但不确定具体时间

  3. 不释放占用的资源锁

  4. 相同优先级的线程拥有获取CPU时间片的机会

4、join()方法

当在线程A中调用线程Bjoin方法,线程A暂停执行,直到线程B执行完毕,线程A继续执行。

5、线程停止(三种方法)

线程停止方式:

(1)标志位 boolean 类型的表示)

(2)Stop  (弃用,不安全会立即解除所有锁定,立即结束线程。)   

(3)interrupt()  只是改变中断状态,而不会中断正在运行的线程,给受阻塞的线程发出一个中断信号,使受阻线程能够退出阻塞状态。

  • 改变线程的中断标识true
  • 如果非阻塞  设置中断标志为true
  • 如果阻塞,若由wait、 sleep、 join引起,抛出异常InterruptedExeception ,清理中断标识重新设置为 false
  • interrupt() 本质:通过触发中断,让开发者决定如何处理线程业务

6、线程的优先级:

线程优先级越高,可能优先执行,仅仅是可能性!!!

(1)优先级从 1-10    最低为1,中等为 5,最高为 10

(2) main默认优先级是5

(3) 线程优先级具有继承性,如果线程A中创建线程B,那么线程B的默认优先级继承线程A的优先级

设置优先级:

public final void setPriority(int newPriority);

/*优先级常量:

MAX_PRIORITY  = 10;

NORM_PRIORITY = 5;

MIN_PRIORITY = 1;  */

取得优先级:

public final int getPriority();

7、守护线程

线程可分为:用户线程和守护线程

守护线程:主要用来“陪伴”用户线程,当一个JVM进程中最后一个用户线程退出,那么守护线程将伴随JVM一起结束。

守护线程举例:GC垃圾回收线程

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值