多线程

线程和进程的区别
  • 进程:系统运行的一个应用
  • 线程:应用中的一个任务
  • 进程要大于线程,一个进程至少一个线程 或 多个线程

如果一个进程,还有一个线程没有杀掉还存活,那么进程还存活(线程依附进程)

并行和并发
  • 并行:多个线程同时执行
  • 并发:10秒钟,服务器的吞吐量
线程的状态分为六种
  1. 初始(new):新建一个线程,还没有调用start方法
  2. 运行(runnable):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
    线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  3. 阻塞(blocked):表示线程阻塞于锁
  4. 等待(waiting):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)
  5. 超时等待(timed_waiting):该状态不同于waiting,它可以在指定的时间后自行返回
  6. 终止(terminated):表示该线程已经执行完毕

状态图:
在这里插入图片描述

线程的两种启动方式
  • 第一种:继承thread
private static class AThread extends Thread {

        @Override
        public void run() {
            super.run();
            System.out.println("do work Thread");
        }
    }
    
public static void main(String[] args) throws ExecutionException, InterruptedException {
        AThread thread = new AThread();
        thread.start(); 
    }
  • 第二种:传入runnable
// 方式一:实现Runnable,无返回值
private static class BThread implements Runnable {

        @Override
        public void run() {
            System.out.println("do work Runnable");
        }
    }
    
public static void main(String[] args) throws ExecutionException, InterruptedException {
    
        BThread bThread = new BThread();
        new Thread(bThread).start();
    }
    
// 方式二:实现Callable,有返回值
private static class WorkerThread implements Callable<String> {

        @Override
        public String call() throws Exception {
            System.out.println("do work WorkerThread");
            Thread.sleep(10000);
            return "run success"; // 返回值
        }
    }

public static void main(String[] args) throws ExecutionException, InterruptedException {
        WorkerThread workerThread = new WorkerThread();
        // FutureTask实现了Runnable接口
        FutureTask<String> futureTask = new FutureTask<>(workerThread);
        new Thread(futureTask).start();
        System.out.println(futureTask.get()); 
    }
    
如何停止线程

不要用stop()方法直接停止,要用和谐的方式interrupt()和isInterrupted()

private static class UseThread extends Thread{
		
		public UseThread(String name) {
			super(name);
		}
		
		@Override
		public void run() {
			String threadName = Thread.currentThread().getName();
			while(!isInterrupted()) { // isInterrupted()默认false,调用了interrupt()就变成true
				// 不sleep
				// System.out.println("线程内循环运行....");

				// sleep
				try {
					System.out.println("UseThread:"+formater.format(new Date()));
					Thread.sleep(3000); // sleep 会把中断信号清除,需要在Exception中再处理一次
				} catch (InterruptedException e) { 
					System.out.println(threadName+" catch interrput flag is "
							+isInterrupted()+ " at "
							+(formater.format(new Date())));
					// interrupt 需要在此内部 调用才能中断了,才能把被清楚的标记修改成true
					interrupt();
					e.printStackTrace();
				}
				System.out.println(threadName);
			}
			System.out.println(threadName+" interrput flag is " +isInterrupted());
		}
	}

public static void main(String[] args) throws InterruptedException {
		Thread useThread = new UseThread("HasInterrputEx");
		useThread.start();
		Thread.sleep(800);
		useThread.interrupt(); //run发放中sleep的话interrupt()会被 InterruptedException e 清除
	}
线程优先级 join() 获取执行权
public static void main(String [] args) throws InterruptedException {
        ThreadJoinTest t1 = new ThreadJoinTest("A");
        ThreadJoinTest t2 = new ThreadJoinTest("B");
        t1.start();
        /**join的意思是使得放弃当前线程的执行,并返回对应的线程,例如下面代码的意思就是:
         程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到线程t1执行完毕
         所以结果是t1线程执行完后,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会
         */
        t1.join(); // 让t1获取执行权
        t2.start();
    }
总结
  • run 和start的区别 ?

run是函数调用 和线程没有任何关系, .start会走底层 会走系统层 最终调度到 run函数,这才是线程。

  • 如何控制线程的执行顺序 ?

join来控制 让t2获取执行权力,能够做到顺序执行

  • 多线程中的并行和并发是什么?

四个车道,四辆车并行的走,就是并行, 四个车道中,五秒钟多少的车流量,多少的吞吐量一样

  • 在Java中能不能指定CPU去执行某个线程?

不能,Java是做不到的,唯一能够去干预的就是C语言调用内核的API去指定才行,这个你回答的话,面试官会觉得你研究点东西

  • 在项目开发过程中需要考虑Java线程优先级吗?

不需要考虑优先级, 因为线程的优先级很依赖与系统的平台,所以这个优先级无法对号入座,无法做到你想象中的优先级,属于不稳定,有风险
因为某些开源框架,也不可能依靠线程优先级来,设置自己想要的优先级顺序,这个是不可靠的
例如:Java线程优先级又十级,而此时操作系统优先级只有2~3级,那么就对应不上

  • sleep和wait又什么区别?

sleep是休眠,等休眠时间一过,才有执行权的资格,注意:只是又有资格了,并不代表马上就会被执行,什么时候又执行起来,取决于操作系统调度
wait是等待,需要人家来唤醒,唤醒后,才有执行权的资格,注意:只是又有资格了,并不代表马上就会被执行,什么时候又执行起来,取决于操作系统调度
含义的不同:sleep无条件可以休眠, wait是某些原因与条件需要等待一下(资源不满足)

  • 在Java中能不能强制中断线程的执行?

虽然提供了 stop 等函数,但是此函数不推荐使用,为什么因为这种暴力的方式,很危险,例如:下载图片5kb,只下载了4kb 等
我们可以使用interrupt来处理线程的停止,但是注意interrupt只是协作式的方式,并不能绝对保证中断,并不是抢占式的

  • 如何让出当前线程的执行权?

yield方法,只在JDK某些实现才能看到,是让出执行权

  • sleep,wait,到底那个函数才会 清除中断标记?

sleep在抛出异常的时候,捕获异常之前,就已经清除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值