线程的理解和初步使用

线程的理解和初步使用

      • 1、线程的理解
      • 2、线程的简单使用

最近学习了一些线程方面的知识,在此记录下。

1、线程的理解

面试的时候经常会被面试官问到这样一个问题:你对线程的理解有多少?,然后我们脑子里就会想到一些在开发过程中用到线程的功能或地方,比如一些:消息推送,实时接收处理一些大批量的数据,等一些场景。说完之后下个问题:你对进程的理解有多少?然后就会想到每一个运行的程序就是一个进程。官方一点的语言一句不会说。。。

有关线程几个概念:

为什么会有线程?:为了充分利用CPU的资源,加快用户的响应时间,提出了线程这一概念。

进程:程序运行资源分配的最小单位。进程内部会有多个线程,会共享这个进程的资源。
线程:CPU调度的最小单位,必须依赖进程而存在。
CPU时间片轮转机制:又称RR调度,会导致上下文切换。

面试官提问完线程后,又问:你对并发的了解有多少?你知道并行么?并行和并发有什么区别?

并行:同一时刻,可以同时处理事情的能力。
并发:与单位时间有关,在单位时间内可以处理事情的能力。

通过多线程实现并发,并行:
➤ java中的Thread类定义了多线程,通过多线程可以实现并发或并行。
➤ 在CPU比较繁忙,资源不足的时候(开启了很多进程),操作系统只为一个含有多线程的进程分配仅有的CPU资源,这些线程就会为自己尽量多抢时间片,这就是通过多线程实现并发,线程之间会竞争CPU资源争取执行机会。
➤ 在CPU资源比较充足的时候,一个进程内的多线程,可以被分配到不同的CPU资源,这就是通过多线程实现并行。
➤ 至于多线程实现的是并发还是并行?上面所说,所写多线程可能被分配到一个CPU内核中执行,也可能被分配到不同CPU执行,分配过程是操作系统所为,不可人为控制。所以,如果有人问我我所写的多线程是并发还是并行的?我会说,都有可能。
➤ 不管并发还是并行,都提高了程序对CPU资源的利用率,最大限度地利用CPU资源。
理解了上面几个名词,我们就会知道:
高并发编程的意义、好处、注意事项

好处

  • 1、充分利用CPU的资源、加快用户的响应时间
  • 2、程序模块化、异步化。

问题

  • 1.、线程是共享资源的,所以会存在冲突;
  • 2、容易导致死锁;
  • 3、启动太多的线程就有搞垮机器的可能。

所以一般情况下,我们在设置线程数的时候会和CPU核心数保持相应的比例。最初的时候,核心数:线程数=1:1,后来微软提出并使用了超线程技术后,核心数:线程数=1:2.

2、线程的简单使用

首先我们要先会使用线程,然后再去深入理解线程的各方面知识。
以Java为例:
启动线程的三种方式:
1、继承java.lang.Thread类;
2、实现java.lang.Runnable接口;
3、实现java.util.concurrent.Callable接口。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ThreadTest {

     static class ThreadRun extends Thread {
        @Override
        public void run() {
            for (int i=0;i<10;i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }

     static class RunnableRun implements Runnable {
        @Override
        public void run() {
            for (int i=0;i<10;i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }

     static class CallableRun implements Callable<String> {
        @Override
        public String call() throws Exception {
            for (int i=0;i<10;i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
            return "hello";
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadRun threadRun = new ThreadRun();
        threadRun.setName("threadRun");
        threadRun.start();

        RunnableRun runnableRun = new RunnableRun();
        Thread thread1 = new Thread(runnableRun);
        thread1.setName("runnableRun");
        thread1.start();

        CallableRun callableRun = new CallableRun();
        FutureTask<String> futureTask = new FutureTask<>(callableRun);
        Thread thread2 = new Thread(runnableRun);
        thread2.setName("callableRun");
        thread2.start();
        System.out.println(futureTask.get());
    }
}

根据Java单继承多实现原则:
继承Thread类:一般如果我们的类只是供线程使用而没有其他的用途就可以使用继承Thread类。
实现Runnable接口:如果类还有别的业务操作,那建议去实现Runnable接口,不影响继承类和实现别的接口。
实现Callable接口:继承Thread类和实现Runnable接口都是没有返回值的。如果想拿到线程的执行结果,换句话说就是如果想要有返回值,就要去实现Callable接口,这个接口可以获取返回结果。

怎么才能让线程安全停止工作?
1、线程自然终止:自然执行完成或抛出未处理异常。
2、调用stop()、resume()、suspend()方法,但是不建议使用。stop()会导致线程不正确释放资源,suspend()容易导致死锁。
3、调用interrupt()方法。调用一个线程的interrupt()方法中断一个线程,并不是强制关闭这个线程,只是跟这个线程打个招呼,将线程的中断标志位置为true,线程是否中断由线程本身决定。
isInterrupted()判断当前ixancheng是否处于中断状态。
static方法interrupted()判定当前线程是否处于中断状态,同时中断标志位改为false。
注意:
方法中如果抛出InterruptedException,线程的中断标志位会被复位成false,如果确实想中断线程,我们自己在catch块里主动调用interrupt()方法。

你可能感兴趣的:(技术开发,java线程)