zoukankan      html  css  js  c++  java
  • java-线程-基础

    线程状态及转化

    借用网上的一幅图:

    说明:
    线程一共分为5种状态

    新建状态(new)

    线程对象被创建后,就进入了新建状态,例如:Thread t = new Thread();

    就绪状态(Runnable)

    线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。
    例如,thread.start()。处于就绪状态的线程,然后等待CPU调度执行。可不是run()方法-_-;

    当如果多次调用start(),这时会报异常。

     public synchronized void start() {
            //A zero status value corresponds to state "NEW".
            if (threadStatus != 0)
                throw new IllegalThreadStateException();
    

    运行(Running)

    线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。

    堵塞(blocked)

    阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种,状态是两种(blocked 和waiting):

    • 等待阻塞 -- 通过调用线程的wait()方法,让线程等待某工作的完成。
    • 同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
    • 其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

    blocked 和waiting 区别,blocked是在临界点外面等待进入,waiting是在临界点里面等待notify,当线程调用了join方法,jion了另外的线程的时候,也会进入waiting状态,等待被它jion的线程结束。

    死亡(Dead)

    线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    线程的创建

    线程创建有3中方式:

    1、继承Thrad:

    Thread t = new Thread(){
        public vvoid run(){
            System.out.println("new Thread");  
        };
    };
    

    2、实现Runnable接口:

    Thread t = new Thread(new Runnable(){
        public void run(){
            System.out.println("new Thread");  
        };
    });
    

    3、使用Callable和Future创建线程

    FutureTask<String> ft = new futureTask<String>(){
        public String call() throws Exception{
            System.out.println("new Thread");  
            return "abc";
        }
    }
    Thread t = new Thread(ft);
    ft.start();
    String result= ft.get();
    

    线程方法

    Object中方法

    wait(),notify(),notifyAll()都是定义在Object类中,它们都是依赖于同步锁,而同步锁是对象锁持有,并且每个对象只有一个!这就是为什么notify(),wait()等函数定义在Object类,而不是Thread类中的原因。

    注意:调用wait/notify/notifyAll一定是在获取对象的锁之后,否则会报错哈!java.lang.IllegalMonitorStateException

    wait()

    方法是将当前线程进入等待(waiting)状态,同时也会让当前线程释放它持有的锁(同步锁),直到其他线程调用此对象的notify()活notifyAll(),唤醒当前对象上的线程(单个或所有),让其进入就绪状态,等待cpu调度,才能继续执行wait之后的代码;

    wait(long timeout)

    也是让当前的线程进入等待(TIMED_WAITING)状态,该方法可以指定超时时间,当调用此对象的notify()或者NotifyAll(),或者超过指定的时间,则线程也会别唤醒,进入就绪状态;

    wait(long timeout,int naous)

    notify()和notifyAll()是唤醒当前对象上的等待线程,notify是唤醒单个线程,而notifyAll则是唤醒所有的线程;

    整体流程是这样:当一个线程获取对象的同步锁后,然后执行直到wait()方法,这时该线程进入等待状态,释放该对象的同步锁,这时另外一个线程(唤醒线程)获取同步锁后(这里的同步锁一定是和等待线程的同步锁是同一个),执行到notify()或notifyAll()后,才能唤醒等待线程,虽然等待线程被唤醒,但是它不能立刻执行,因为唤醒线程还持有该对象的同步锁,必须等待唤醒线程释放了对象的同步锁之后,等待线程才能获取对象的同步锁进而继续运行。

    Thread中方法

    yeild(),sleep()都是定义在Thread类中

    yeild()

    它的作用是让步,也就是说由正在运行的状态进入到就绪状态,从而让其他具有相同优先级的线程获取执行权,但是,并不能保证在当前线程调用yeild方法后,其他线程一定能获取执行权,也有可能是当前线程再次进入运行状态继续执行。

    sleep()

    让当前线程休眠,即让当前线程由运行状态转换到阻塞状态,sleep可指定休眠时间,当线程的休眠时间超过了指定的时间,线程会被唤醒,由阻塞状态变成就绪装,然后等待cpu调度。
    特别注意,sleep()是不会释放对象的同步锁,就是单纯的让线程阻塞。

    interrupt()

    当线程调用interrupt(),只是设置了线程的中断状态,并不会终止线程,剩下的是由你自己来处理该线程怎么办,wait(), wait(timeout), join(), sleep(timeout), await(),await(timeout)等方法都是可以被interrupt()方法中断的。

    线程释放锁一个是方法执行完、调用wait、代码抛出异常。

  • 相关阅读:
    PHP、asp、aspx、JSP一句话
    Linux 修改时区(PDT修改为CST)
    m0n0防火墙安装配置方法
    kali 使用John破解zip压缩包的密码
    Linux 挂载windows共享文件夹
    博客园添加粒子特效
    wpscan 更新超时报错
    kali 攻击wordpress + trunkey linux wordpress 安装方法
    Kali和Metasploitable2的网络配置
    设计模式之观察者
  • 原文地址:https://www.cnblogs.com/xckxue/p/8677673.html
Copyright © 2011-2022 走看看