笔记:线程小白基础

2020-09-01  本文已影响0人  盐海里的鱼

进程与线程的区别

1.进程:操作系统调度的最小单元 如任务管理器里每一个应用就是一个进程
2.线程:CPU调度的最小单元,一个进程通常可以包含多个线程。

线程间的调度机制

1.线程间在cpu调度采用的算法是RR调度,由于每一次切换都是一次上下文切换 需要临时存储和获取将停止线程与将执行线程的数据 所以每次切换都是需要耗费性能。
2.线程调度——时间片轮转/CPU核心调度


线程调度

线程的并发与并行

创建与启动线程的三种方式

class MyThread extends Thread{
    @Override
    public void run() {
        System.out.println("MyThread=======================>"+getName());
    }
}

 //TODO: 继承Thread
        MyThread myThread = new MyThread();
        myThread.start();
class  MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("MyRunnable=======================>"+Thread.currentThread().getName());
    }
}

  //TODO: 实现Runnable
        MyRunnable myRunnable = new MyRunnable();
        new Thread(myRunnable).start();
class  MyCallable implements Callable<String> {

    @Override
    public String call() throws Exception {
        System.out.println("MyCallable=======================>"+Thread.currentThread().getName());
        return "MyCallable";
    }
}

 //TODO: 附带返回值实现Callable
        MyCallable myCallable = new MyCallable();
        FutureTask<String> futureTask = new FutureTask<>(myCallable);
        new Thread(futureTask).start();
        try {
            System.out.println(futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
控制台打印

线程的中止

1.抢占式停止stop()(不安全,不推荐)
2.协作式停止 interrupt()

class MyThread extends Thread{
    @Override
    public void run() {
        int i=0;
        while (!isInterrupted()){
            i++;
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
                interrupt();
            }
            System.out.println("MyThread=======================>"+i+"   "+getName());
        }
    }
}

发起中断信号

  myThread.start();
    try {
       Thread.sleep(5000);
    } catch (InterruptedException e) {
       e.printStackTrace();
   }
  //TODO: 发起中断
  myThread.interrupt();
线程中止

线程的常用方法

线程常用方法.png
  Thread threadA = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("HELLO TA");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        Thread threadB = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("HELLO TB");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        threadA.start();
        threadB.start();

结果:

抢占式无序.png
        threadA.start();
        try {
            threadA.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        threadB.start();

结果:

使用join.png

面试题:

答:run是函数调用 和线程没有任何关系, .start会走底层 会走系统层 最终调度到 run函数,这才是线程。

答:join来控制 让t2获取执行权力,能够做到顺序执行

答:四个车道,四辆车并行的走,就是并行, 四个车道中,五秒钟多少的车流量,多少的吞吐量一样

答:不能,Java是做不到的,唯一能够去干预的就是C语言调用内核的API去指定才行

答:不会考虑优先级,为什么呢? 因为线程的优先级很依赖与系统的平台,所以这个优先级无法对号入座,无法做到你想象中的优先级,属于不稳定,有风险 因为某些开源框架,也不可能依靠线程优先级来,设置自己想要的优先级顺序,这个是不可靠的。 例如:Java线程优先级又十级,而此时操作系统优先级只有2~3级,那么就对应不上

答:sleep是休眠,等休眠时间一过,才有执行权的资格,注意:只是又有资格了,并不代表马上就会被执行,什么时候又执行起来,取决于操作系统调度
wait是等待,需要人家来唤醒,唤醒后,才有执行权的资格,注意:只是又有资格了,并不代表马上就会被执行,什么时候又执行起来,取决于操作系统调度
含义的不同:sleep无条件可以休眠, wait是某些原因与条件需要等待一下(资源不满足)

答:虽然提供了 stop 等函数,但是此函数不推荐使用,为什么因为这种暴力的方式,很危险,例如:下载图片5kb,只下载了4kb 等 我们可以使用interrupt来处理线程的停止,但是注意interrupt只是协作式的方式,并不能绝对保证中断,并不是抢占式的

答:yield方法,只在JDK某些实现才能看到,是让出执行权

答:sleep在抛出异常的时候,捕获异常之前,就已经清除

上一篇 下一篇

猜你喜欢

热点阅读