java 多线程

多线程的实现方式:继承Thread类,实现Runable接口,实现Callable接口

1、继承Tread类:

public class MyThread extends Thread {

    private int count = 1;

    @Override
    public void run() {
        System.out.println("MyThread + " + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }
}

缺点:java是单继承的,如果MyThread还需要继承其他类,是无法继承的,另外count是线程的一个局部变量,如要在主线程中共享该变量的值是没法共享的

2、实现Runnable接口,Runnable本身只是一个接口,只有一个run()方法,需要将接口的实例传递给Thread及其子类才能实现一个线程

源码:

public class MyThreadRunnable implements Runnable {
    private int count = 7;

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "---" + count);
        for (int i = 0; i < 7; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + count--);
        }
    }

    public static void main(String[] args) {
        MyThreadRunnable runnable = new MyThreadRunnable();
        Thread t1 = new Thread(runnable);
        t1.setName("runnable1");
        t1.start();

        Thread t2 = new Thread(runnable);
        t2.setName("runnable2");
        t2.start();
    }
}

优点:解决了java单继承的问题,变量可以共享,实际上是多个线程共享了Runnable接口的实例以及变量,所以多数时候使用线程都应该选择实现接口的方式

3、实现Callable接口,从源码上看,与Runnable接口的区别是有返回值,并且允许抛出异常

源码:

Callable接口需要借助FutureTask来实现线程,实际上实现Runnable接口的是FutureTask<>

public class MyThreadCallable implements Callable<String> {
    private int count = 9;

    @Override
    public String call() throws Exception {
        for (int i = 0; i < 9; i++) {
            System.out.println("计数:" + count--);
        }
        return "count=" + count;
    }

    public static void main(String[] args) {
        MyThreadCallable callable = new MyThreadCallable();

        FutureTask<String> task = new FutureTask<>(callable);

        Thread thread = new Thread(task);
        thread.start();

        //可以获取返回值和抛出异常
        try {
            String result = task.get();
            System.out.println("获取返回值:" + result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

4、多线程执行的优先级问题,即线程抢占CPU执行的几率问题,有2种调度模型

分时调度模型:轮流获取cpu执行权,平均分配cpu的使用时间片

抢占式调度模型:优先级高的线程使用cpu的几率要高些,如果优先级一样,则随机选

java使用的是抢占式调度模型,通过设置优先级参数实现,优先级的int值范围1<priority<10,默认是5:设置优先级

thread.setPriority();

6、设置为守护线程thread.setDaemon();

守护线程和非守护线程:

当2个线程(一个守护线程,一个非守护线程)运行时,当非守护线程执行完毕,守护线程也没有必要继续运行

7、主线程和子线程

主线程:main函数执行的线程为主线程,在main函数里面创建的线程均为子线程,main函数是一个非守护线程(不能设置为守护线程),当主线程结束后,其他线程没有执行完,仍然可以继续运行:

主线程执行完毕,子线程仍然在等待 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值