从0开始深入理解并发、线程与等待机制1

进程与线程

进程就是一个app实例,是资源分配的最小单位

线程是最小的cpu调度单位,线程和进程是包含关系,线程依赖进程

Java当中有进程必然会有线程

进程间的通信:IPC(面试题)

管道:匿名管道(pipe)一般用于父子进程间的通信,父fork一个子进程,子与父进程就没有关系了,如果父子进程之间想要通信的话可以用匿名管道

命名管道(named pipe):就是两个不同进程间想要通信可以共同访问一个命名管道

信号:信号是在软件层次上对中断机制的一种模拟,用于通知进程有事情发生

消息队列:内存中建立起来内存消息队列

共享内存:它可以使多个进程共同访问同一块内存空间

信号量:主要作为进程之间及同一种进程的不同线程之间的同步和互斥手段

套接字:它可以用于网络中不同机器之间的进程通信,基于socket的通信,类似于mysql,既可以本地连接,别的机子也可以访问;这种方式不用经过网络协议栈,不需要打包拆包、计算校验、维护序号和应答等,比纯粹基于网络的进程间通信效率更高

上下文切换

就相当于在代码中写的局部变量,并且并发一定会引起上下文切换

一次上下文切换大概需要5k-2w的时钟周期,因此代码优化的时候需要观察上下文切换的次数

启动线程的方法

继承Thread接口,实现Runnable接口,在run方法中书写业务代码

拿到实例,并new Thread(“xxx”).start启动

官方注释说是两种:new Thread()和实现Runnable接口

此外:Callable接口和线程池也可以启动线程

Callable接口和Future接口

有一个需求:做一个累加,累加完之后,需要拿到累加的结果

Callable 接口可以接收返回值,Runnable接口的run()方法没有返回值

线程是异步执行的,有可能因为休眠的关系,我线程都执行完了,才返回结果

就需要采用Future类的get()方法就可以拿到Callable

Future->RunnableFuture->FurureTask

也就是说需要用FutureTask包装一下Callable

FutureTask<> futureTask = new FutureTask<>(callable);

new Thread(futureTask).start();

futureTask.get();即可拿到返回值

终止线程的方法

自然终止

代码运行结束

代码报错,抛出异常

主动终止

有stop(),挂起suspend()

不过这两个方法都被废弃了,挂起suspend()不会释放任何资源(锁)

stop()太强力了,可能导致写文件时没有正常的结束标志导致文件损坏

一般使用的都是中断方法:interrupt()是用来中断某个线程的,不过它不会立马去中断线程运行,而是会将中断标志位更改为true

interrupted()是用来判断标志位是否为true,判断完之后还会给回false

isinterupted()是用来判断标志位是否为true

不建议自己自定义变量控制线程结束的标志位,因为调用了阻塞类方法除非调用唤醒方法,不然会很迟钝的去感受到这个变量的转化

private static class UseThread extends Thread{

		private boolean cancel;

		public UseThread(String name) {
			super(name);
		}

		public void setCancel(boolean cancel) {
			this.cancel = cancel;
		}

		@Override
		public void run() {
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName+" interrrupt flag ="+isInterrupted());
			//while(!isInterrupted()){
				//Thread.sleep();

			//while(!Thread.interrupted()){
			while(true){
				System.out.println(threadName+" is running");
				System.out.println(threadName+"inner interrrupt flag ="
						+isInterrupted());
			}
			//System.out.println(threadName+" interrrupt flag ="+isInterrupted());
		}
	}

	public static void main(String[] args) throws InterruptedException {
		UseThread endThread = new UseThread("endThread");
		endThread.start();
		Thread.sleep(20);
		endThread.interrupt();//中断线程,其实设置线程的中断标识位=true

	}

start()和run()方法

连续两次执行start()/run()方法可以吗?

连续执行start()方法会抛出一个异常出来,run()方法则不会,调用几次就执行几次

start()和run()方法的区别是什么

Java是面向对象的语言,将线程抽象成了Thread类,通过new Thread()方法只能说明是JVM堆上面有这么一个对象而已和线程没有关系。把这个对象实例和操作对象的线程挂钩的是调用了start()后才将这个实例和操作系统中的某一个线程挂钩。一个对象实例只能和一个线程对应,所以说不能调用多次start()

run()只是一个成员方法,可以单独反复执行,只是告诉线程该去哪里执行业务代码。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

—熙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值