多线程系列

1.什么是线程

将线程理解为轻量级进程,它与进程的最大的区别是:

多个线程共享一个进程资源;

对于OS的许多资源的分配和管理(如内存)通常都是进程级别的,线程只是os调度的最小单位;

相对于进程来说更轻量,上下文信息更少,创建、销毁更简单,若线程被挂起,不会导致整个进程被挂起。

2.在java中如何使用线程

  • 实现Runnable接口,然后通过new Thread(new RunnableImpl()).start();创建线程。
public interface Runnable {
    public abstract void run();
}
  • 继承Thread类(Thread类自身实现了Runnable接口), new MyThread().start()创建线程。
start()方法是怎么启动线程的?  -  摘自《java特种兵》

实现方式1
基于Kernel Thread(KLT)的映射来实现:KLT是内核线程,内核线程由OS直接完成调度切换,它相对应用程序的线程来讲只是一个借口,
外部程序会使用一种轻量级进程(Light Weight Process, LWP)来与KLT进行一对一的借口调用。 也就是说,进程内部会尝试利用OS的内核线程去参与实际的调度,而自己使用API调用作为中间桥梁与自己的程序交互。

3.JAVA中线程的状态

  • NEW (执行 start()之前,需注意:调用了start()并不代表状态立即改变,中间还有一些步骤,要看那些中间步骤是否已经完成了)
  • RUNNABLE (可以理解为活着并尝试征用CPU)
  • BLOCKED(阻塞状态,或者说线程已被挂起, 是在多个线程有同步操作的场景, 比如正在等待另一个线程的synchronized 块的执行释放, 或者可重入的 synchronized块里别人调用wait() 方法, 也就说线程在等待进入临界区)
  • WAITING (一个线程拥有锁对象后,执行wait()方法)
  • TIMED_WAITING (sleep()之后进入此状态)
  • TERMINATED (run()方法执行结束后就处于此状态,在操作系统内部可能已经注销了相应的线程,活着将它复用给其他需要使用线程的请求)

4.线程优先级

cpu的资源是有限的,在某些情况下,我们可以设置线程的优先级,让OS根据不同的优先级进行调度

线程调度的优先级,每个OS都有不同的实现,java虚拟机为了兼容各种OS设定了1-10个优先级,理论上数字越大,优先级越高。

而某些OS可能只有3-5个线程,那么jvm会根据实际情况将 1-10这10个数字与OS的线程优先级做一个映射关系。

那么思考一下,很有可能 优先级3 和  优先级5 在OS中是同一个优先级。

java中通过setPriority(int)方法来设置一个线程的优先级。 在实际工作中,通常将优先级设置为普通(5,默认),最大(10),最小(1)。

5.守护线程

java中有两类线程 User Thread 和 Daemon Thread 

守护线程--也称“服务线程”,在没有用户线程可服务时会自动离开。(GC 即为一个守护线程)

java中通过setDaemon(true)  将一个线程设置为守护线程,但是需注意两点

   1.thread.setDaemon(true)必须在thread.start()之前设置,否则将会抛出IllegalThreadStateException异常

   2.在Daemon线程中产生的新线程也是Daemon的

Thread中setDaemon实现

    public final void setDaemon(boolean on) {
        checkAccess();
        if (isAlive()) {
            throw new IllegalThreadStateException();
        }
        daemon = on;
    }
原文地址:https://www.cnblogs.com/captains/p/multi-thread01.html