Java并发之基础知识

作者: 第四单元 | 来源:发表于2018-12-15 21:15 被阅读55次

    一. 线程的创建方式

    1.1继承Thread类

    重写run()方法即可。

    public class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("MyThread is running!");
        }
    
        public static void main(String[] args) {
            MyThread myThread = new MyThread();
    
            myThread.start();
        }
    }
    
    1.2实现Runnable接口
    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("MyRunnable is running");
        }
    
        public static void main(String[] args) {
            Thread myRunnable = new Thread(new MyRunnable());
    
            myRunnable.start();
        }
    }
    

    2 线程的5个状态

    新建
    当用new操作符创建一个线程对象后,如new Thread(r),还没有调用start()方法之前的状态

    可运行
    调用start()方法之后且没有被阻塞,也没在等待某个条件。可能正在运行也可能没有运行(等待CPU时间片)。在CPU分配时间片给多个线程,使它们轮流执行的过程中,不过实际有没有运行都处于可运行状态。

    阻塞
    当一个线程视图获取一个内部对象锁(synchronized),而该锁被其它线程持有,则该线程进入阻塞状态。内部对象锁是使用monitor对象实现的,每个monitor维持两个队列,一个是entry_list,一个wait_list。分别用于保存想获取锁的线程和等待条件的线程。(wait_list中的线程处于等待态)。

    等待
    等待一个条件时。1.Object.wait方法,进入wait_list队列,等待调用Object.notify()或Object.notifyAll()方法。2.等待ReentryLock或Condition时。3.调用Thread.join()方法

    计时等待
    有几个方法有一个超时参数。调用它们导致线程进入计时等待状态。这一状态将一直保持到超时期满或者接收到适当的通知。
    这些方法有:Thread.sleep,Object.wait、Thread.join、Lock.tryLock、Condition.await等方法的计时版。

    终止
    线程因两个原因之一被终止

    • 因为run方法正常退出而自然结束
    • 因为一个没有捕获的异常终止了run方法而意外死亡

    3 Object类中线程相关的方法

    3.1 wait()方法

    线程调用一个对象的wait()方法之前需要先获取到这个对象的内部对象锁,否则会抛出IllegalMonitorStateException异常。另一个可能的异常是:InterruptedException

    调用这个方法使线程进入等待状态,在对象monitor对象的等待队列里默默等待,别的线程调用notify()或notifyAll()方法来唤醒。并且会释放获取到当前对象的锁。

    这个方法常常用来等待某个条件的满足:

    synchronized(obj) {
      while(条件不满足) {
          obj.wait() 
      }
      //满足条件了,尽情干想干的事吧!
    }
    

    它还有个带计时的版本wait(long timeout),这是个native方法,是wait的真正实现。其实wait的实现就是调用了wait(0)而已。

    3.2 notify()方法

    和wait()方法配合使用。随机唤醒在对象monitor等待队列中一个线程。
    同样需要先获取内部对象锁才能调用,否则会抛出IllegalMonitorStateException异常。
    唤醒只是将线程从等待态切换到Runnable(可运行)态,不一定保证能立马执行(还有CPU分配时间片的因素)
    调用此方法不会释放内部对象锁。

    3.3 notifyAll()

    唤醒所有的等待线程。
    调用此方法需要先获取内部对象锁。
    调用此方法不会四方内部对象锁。

    4 Thread类中线程相关的方法

    4.1 sleep(long millis)方法

    方法声明:

    public static native void sleep(long millis) throws InterruptedException;
    

    是个静态方法,通过Thread.sleep()调用。使当前线程休眠指定时间再进入runnable状态。调用后进入阻塞态,不会释放内部对象锁。

    4.2 join()方法

    方法声明:

    public final void join() throws InterruptedException ;
    

    当前线程调用指定线程的join()方法,会等待该线程结束后再继续执行。
    join方法还有一个带参数的版本,等待线程结束或到达指定时间再继续执行。
    调用join后进入阻塞状态。

    相关文章

      网友评论

      • 脚本1894:能点下我的头像,看下我的文章《奶奶说:我不怕》吗?也许你的一个不经意浏览,就帮助了一个家庭,谢谢你,如果打扰到你了,先说声抱歉。
        脚本1894:@第四单元 谢谢你
        第四单元:@脚本1894 已浏览点赞
      • 脚本1894:厉害👍,这些好难学😂

      本文标题:Java并发之基础知识

      本文链接:https://www.haomeiwen.com/subject/xhrahqtx.html