线程学习一:线程基础

1、什么是进程、线程、多线程 ?

     操作系统中,进程是分配和调度系统资源的最小单位,而线程是进程中的能独立执行的最小单元 ;

     一个进程中至少有一个线程,称为主线程,主线程还能创建其他线程,所有线程称为多线程 ;

     在单核CPU操作系统中,多个线程或者进程采用时间片转轮的抢占式方式或取CPU,由于单个时间片很短,给人的感觉就像是多个进程或线程在同时执行,这是伪并行;

     在多核CPU操作系统中,线程或进程数小于CPU数量,那么足以每个进程或者线程各分配一个CPU同时运行,实现真正的并行 。

2、 JVM 线程与操作系统的线程啥关系 ?

     先理解 线程模型

  • 内核级别线程

    内核级别线程(Kernel-level threading)是指用户进程通过内核提供API创建的线程。这样用户进程里的线程和内核调度的线程是1:1对应的。这也就最简单的线程管理方法。

  • 用户级别线程

     用户基本线程(User-level threading)是指 用户进程自己实现线程机制。在这种情况下,内核是不知道有多少线程存在的,同时线程上下文切换更快,而且在不支持多线程的操作系统上也能实现多线程。但是,用户级别的线程也带来相当大的坏处,比如不能充分利用多处理器(多核)系统;如果进程中的一个线程执行阻塞的I/O请求,那么整个用户进程都会被阻塞。

  • 混合线程

     混合线程是内核级别线程和用户级别线程的混合体,提供了以上两种模型的优点,但是带来很大的复杂性。


     JVM 1.1之前使用的是 用户级别线程,又称绿色线程  。

     JVM 1.1之后,由于用户级别线程的局限性,之后改为映射内核级别线程 或者进程 。

     在linux2.6之前,操作系统还没有线程,当时映射的是进程和微进程,微进程能进行一定的互相通信,进程之间是完全不能互相通信的 。

     linux 2.6 之后,就是目前的,就都是内核级别线程了。


3、java 线程的创建(2种方式)

    阅读java.lang.Thread类的源码:

   private Runnable target;
      @Override
      public void run() {
          if (target != null) {
              target.run();
          }
       }
    很明显,如果我们要创建一个能跑自己逻辑的Thread,就只有2个途径

    1、为属性target赋值一个实现了Runnable对象,该对象实现了自己的run方法 。而这个赋值没有set方法,只有一个途径,构造函数(源码如下)

public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

     2、类继承Thread,并且重写run方法 。

    示例如下 :

  

/**
 * 线程基础一:线程的创建
 * @author xubo
 *
 */
public class ThreadStudyOne {

	/**
	 * 通过Thread(Runnable A)进行创建
	 */
	private static Thread getThreadFromRunnable() {
		return new Thread(new Runnable() {
			@Override
			public void run() {
				//what you want to do !
				System.out.println("这是通过Thread(Runnable A)构造函数创建的");
			}

		});
	}

	/**
	 * 继承
	 */
	public static class myThread extends Thread {
		@Override
		public void run() {
			//what you want to do !
			System.out.println("这是通过重写父类Thread的run方法创建的");
		}
	}

	private static Thread getThreadFromOverride() {
		return new myThread();
	}

}

4、进程的调度 ,必须使用Thread.start()方法,直接使用run方法是没有创建线程的  。

 源码如下

    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

5、Thread常用方法 与 属性

        a、先级 priority :

     有get与set方法 ,有低中高3个常量,Thread.MIN_PRIORITY=0,Thread.NORM_PRIORITY=5,THREAD.MAX_PRIORITY=10

        b、执行  start() :

     调用操作系统内核API创建一个线程进行执行任务 。

         c、停止  stop() :

     调用瞬间,对应线程抛出ThreadDeathException,导致线程异常终止,会有监视器(锁对象)未释放的风险,
目前在JDK中标记为过时 

          d、打断  interrupt() :

         调用interrupt()方法,对应线程如果处于sleep睡眠状态,会直接跑出Interrupted异常,否则对应线程
继续执行,只是状态改为了打断状态 。这个方法只能终止睡眠状态线程,使用时根据需要考虑stop()与interrup()。

             e、睡眠 sleep ():

       sleep(Long m) 表示睡眠多少毫秒 。 如果是sleep(0),表示希望系统直接进行一次CPT资源抢占分配 ,
给低优先级线程一个运行的机会。该方法不会释放锁。

             f、暂停 与 唤醒  wait() ,notify(),notifyAll(),yield() :

        wait(Long m) : 线程阻塞并释放锁,直到被notify()或notifyAll唤醒 ,或者等待m毫秒时间。
     wait() : 线程阻塞并释放锁,知道被notify()或notifyAll唤醒,否则一直等待
     yield() : 线程阻塞并释放锁,知道线程组里面的其他线程执行完成再执行本线程。 

           g、线程组 ThreadGroup :

      对线程进行了隔离 。 只有同一线程组内的线程才能够互相调用与阻塞。不自己设置线程组的情况下,
都是继承创建该线程的线程组。以此向上推,可知,同一个线程源头创建的线程一般都属于一个线程组。
是否有权限操作某线程a,可用a.checkAccess()方法。

           h、执行等待 join() :

      join(Thread A) , 强制在A线程执行完后再继续执行本线程。

           i、守护线程

        与基本线程其实也没是区别,
        主要特性2点:作用是为被守护的线程提供监控和服务;会因为所有被守护的线程的结束而自动结束。  
        调用setDaemon()方法就能设置守护线程了,在守护线程中创建的线程都是守护线程。

 


    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值