Java面试问题笔记

一、Java中有哪几种方式来创建线程执行任务 ?
  (可以说有一种也可以有四种)
1.继承Thread类
public class oneThread extends Thread{


    public static void  main(String[] args) {
        oneThread thread = new one ();
        Thread.start();
    }

    @Override
    public void run() {
        System.out.println("hello one")
    }
//启动线程并运行run 中的任务
}
缺点就是因为这个类是单继承类所以要继续继承一些其他的类就需要另外的方法 了
总结:重写的是run()方法,但是占用了继承的名额,Java中的类是单继承的。
   (另外我们应该注意到的是 ,Java中的接口是可以多继承的)

2.实现Runnable接口
public class oneThread implements Runnable{


    public static void  main(String[] args) {
        Thread thread = new Thread (new oneThread());
        Thread.start();
    }

    @Override
    public void run() {
        System.out.println("hello one")
    }
//启动线程并运行run中的任务
}
这里想要使用的话可以去New一个Thread对象,但是不同的是在Thread thread = new Thread (new oneThread());可以将实线内的对象传进去
实现的 Runnable接口,这种方式更加实用。

3.实现Callable接口
public class oneThread implements Callable<String>{


    public static void  main(String[] args) throws ExecutionException.Interr{
        FutureTask<String> futureTask = new FutureTask<>(new oneThread());
        Thread thread = new Thread (futureTask);
        Thread.start();
        String result = futureTask.get();
        System.out.println(result)
    }

    @Override
    public void call() {
        return "S"
    }
这个方法需要用到FutureTask,再由FutureTask传回Thread方法,这个接口的好处是可以得到运行的结果
但是这种方式的最终本质也是Runnable的实现方式
(虽然Java的类与类之间是单继承的,但是接口之间是可以多继承的)

4.利用线程池来实现线程
总结:虽然四种方式都是分开的,但是归根到底来说都是Runnable方法来实现的。


二、为什么不建议用Executors来创建线程池?
1.FixedThreadPool
public static ExecutorService newFixedThreadPool(int nTheads) {
    return new FixedThreadPool(nTheads, nTheads,
                               OL,TimeUnit.MILLISECONDS,
                               new LinkedBlockingQueue<Runnable>());
}

对于创建队列为LinkedBlockingQueue,是一个无界阻塞队列,如果使用该线程池执行任务,如果任务过多就会不断的添加到队列中
任务越多占用的内存就越多,最终可能耗尽内存,导致OOM
(OOM:全称“Out Of Memory”,翻译成中文就是“内存用完了”,来源于java.lang.OutOfMemoryError。)
除此之外,使用Executors来创建线程池也不能自定义线程的名字,不利于排查问题,所以建议直接使用ThreadPoolExecutor来定义线程池,这样可以灵活控制

三、Java中线程的状态
       1、5种(一般是针对传统的线程状态来说,处于操作系统的层面)
            新建状态(new)->就绪状态,也称为可运行状态,此时得到CPU调度(ready)->运行状态(running)->
 在遇到wait()、sleep()、join()、时就会进入等待状态(waiting)
从等待状态得到资源重新回到就绪状态,再度回到就绪状态最后运行完毕进入结束状态(stopping)
      2、在Java中有6种(推荐答案)
                 NEW、RUNNING、BLOCKED、WAITING、TIMED_WAITING、TERMINATED
NEW:   对应CPU状态中的新建,这个时候CPU无法调度 
RUNNING:得到资源线程直接开始运行
BLOCKED:    线程得锁失败后进入此状态
WAITING:   线程执行了wait()方法,此时需要进行手动唤醒 
TIMED_WAITING:  线程执行了sleep()方法进入此状态,等到时间一到进入自动唤醒的状态            TERMINATED:线程的方法执行完毕进入此状态      

                                                  

四、Java中如何停止线程
  1、stop()方法,太过于暴力,已经过时。不推荐使用
  2、使用共享变量:修改全局的共享变量破坏死循环,让线程退出死循环,但是需要留下一个接口。
  3、interrrupt()方法:在默认情况下有一个中断标记位:false,注意这种方法是在线程内部,更加推荐
           isInterrupted()直接拿到状态进行操作
           interrupt() 中断标记位为ture
           interrupted()  将中断标记为归位
以上的三种方法中,2、3两种就算让线程的run方法结束,无论是return结束还是抛出异常结束都可以

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值