• 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html
  • 极客专栏正式上线!欢迎访问 https://www.jikewenku.com/topic.html

Java线程状态

技术杂谈 勤劳的小蚂蚁 5个月前 (01-10) 102次浏览 已收录 0个评论 扫描二维码

Java多线程是大多面试场合必问的高频问题,本人在面试美团点评、小红书、金山WPS和海康威视时,被多次问到过 「Java中创建线程有哪几种方式?线程又有哪几种状态?」,在此并针对 「Object类中wait()、notify()和notifyAll()方法的具体使用」 进行一个系统的梳理与总结。

参考答案

Java中创建线程有哪几种方式?
JDK1.5以前,一种是继承Thread类,另一种是实现Runnable接口(推荐使用),两种方式都需要要通过重写run()方法来定义线程行为。
JDK1.5以后,创建线程还有第三种方式:实现Callable接口,该接口中的call()方法可以有返回值,并可以抛出异常。
具体实现代码不再赘述。
Java中线程有哪几种状态?
Java中调用线程的getState()方法可以确定一个线程的当前状态。其中,线程主要有以下6种状态:
  • NEW(新创建)
  • RUNNABLE(可运行)
  • BLOCKED(被阻塞)
  • WAITING(等待)
  • TIMED_WAITING(计时等待)
  • TERMINATED(终止)
其中,线程相关方法与状态关系示意图如下:
方法与状态关系示意图
wait()、notify()和notifyAll()方法的具体使用
Object类有哪些方法?」中介绍了相关方法的主要作用,在此主要介绍这些方法所引起的线程状态的改变情况。
  • wait()方法:线程由RUNNABLE状态到WAITING状态。
  • wait(timeout)方法:线程由RUNNABLE状态到TIMED_WAITING状态。
  • notify()方法:线程由WAITING或TIMED_WAITING状态到RUNNABLE状态。
  • notifyAll()方法:线程由WAITING或TIMED_WAITING状态到RUNNABLE状态。
wait()、notify()和notifyAll()方法为什么定义在Object类中?
wait,notify和notifyAll都是锁级别的操作,所以把他们定义在Object类中是因为锁属于对象。
另外,wait()、notify()和notifyAll()三个方法用于线程通信,要求其只能在synchronized声明的方法或synchronized代码块中使用,否则会报java.lang.illegalMonitor StateException的异常。

扩展阅读——生产者消费者问题

是否涉及多线程的问题?是!生产者和消费者相当于多线程,而店员类似共享数据。
是否涉及共享数据?是,店员处产品数量,故要考虑线程安全的问题,线程同步。
是否涉及线程的通信问题?是,存在生产者与消费者的通信问题,可使用wait()、notify()和notifyAll()来实现。
public class TestProduceConsume {
    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        Producer p1 = new Producer(clerk);
        Consumer c1 = new Consumer(clerk);
        Thread t1 = new Thread(p1);// 生产者线程1
        Thread t2 = new Thread(c1);// 消费者线程1
        Thread t3 = new Thread(p1); // 生产者线程2
        t1.setName(“生产者1”);
        t2.setName(“消费者”);
        t3.setName(“生产者2”);

        t1.start();
        t2.start();
        t3.start();
    }
}

class Producer implements Runnable // 生产者
    private Clerk clerk;

    public Producer(Clerk clerk) {
        this.clerk = clerk;
    }

    public void run() {
        System.out.println(“生产者开始生产产品!”);
        while (true) {
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            clerk.addProduct();
        }
    }
}

class Consumer implements Runnable // 消费者
    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }

    public void run() {
        System.out.println(“消费者开始购买产品!”);
        while (true) {
            try {
                Thread.currentThread().sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            clerk.consumeProduct();
        }
    }
}

class Clerk // 店员 类似共享数据
    private int product;

    public synchronized void addProduct() {
        if (product >= 20) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            product++;
            notifyAll();
            System.out.println(Thread.currentThread().getName() + “:生产”
                    + product);
        }
    }

    public synchronized void consumeProduct() {
        if (product <= 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            System.out.println(Thread.currentThread().getName() + “:消费”
                    + product);
            product–;
            notifyAll();
        }
    }


丨极客文库, 版权所有丨如未注明 , 均为原创丨
本网站采用知识共享署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议进行授权
转载请注明原文链接:Java线程状态
喜欢 (0)
[247507792@qq.com]
分享 (0)
勤劳的小蚂蚁
关于作者:
温馨提示:本文来源于网络,转载文章皆标明了出处,如果您发现侵权文章,请及时向站长反馈删除。

您必须 登录 才能发表评论!

  • 精品技术教程
  • 编程资源分享
  • 问答交流社区
  • 极客文库知识库

客服QQ


QQ:2248886839


工作时间:09:00-23:00