1-并发编程概念

↘锁芯ラ 提交于 2020-01-27 18:53:11

一、基础

1、cup核心数据与线程数 早期是1:1关系
但后internet优化,提一核可以同时处理2个线程,所以现在核心数据与线程 1:2

2、cpu时间片轮询机制,cpu在执行任务的时候是把cpu分成一段段时间片,因为时间片太短我们感知不到

3、并发和并行
并行:同一时刻处理事情的能力
如比:食堂有8个打饭窗口,那么可以同时处理8个人打饭
并发:时间段内处理事情的能力
如比:一个人打饭需1分钟,那么食堂10分钟内的并发能力就是:8x1x10 = 80个, 10分钟内可处理80个人打饭。

4、并发编程好处意义:提升cup利用效,模块化方法
5、注意事项:注意线程安全,容易死锁,线程太多 机器宕机

二、并发编程

有几种方式创建2种线程

类Thread:java对线程的抽象
Runnable: 对任务和业务逻辑的抽象
Thread threa = Thread(new Runnable())
线程如何中断?
Stop为什么不建议使用:会使线程立刻结束,而资源不会正常释放
Suspend()强制线程挂起,不会释放锁,可能会引起死索
Thread线程中断:
如果要中断线程,那么使用interrupt设置中断标志位
中断线程实现:
interrupt():对线程发起中断:并不是真正终止线程,给线程一个中断标志位(只是跟线程打招呼,线程不会立即停止,也可能不理会),线程是协作式,不是枪占式的(只是通知,但终止,由线程自已决定)
**isInterrupt() :**检测当前线程中断标志位是否true
**静态interrupted(),**检测当前线程中断标志位是否true,如果为true把中断标志位清除改成false

通常用interrupt()方法和isInterrupt结合使用中断线程
在需要中断的情况下调用interrupt()设置标志位,用while(!interrupted()){ 处理逻辑};如果!interrupted()=false ,那么结束run方法,就可以达到线程中断的目的。

private class UserThread extends Thread{

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

	@Override
	public void run() {
		String threadName = Thread.currentThread().getName();
		System.out.println(threadName+" interrrupt flag ="+isInterrupted());
		while(!isInterrupted()){
			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 {
	Thread endThread = new UseThread("endThread");
	endThread.start();
	Thread.sleep(20);
	endThread.interrupt();//中断线程,其实设置线程的标识位true
}

不建议自己定义一cancel booble型去是否发起了中断。
因为如果在while(cancel){ 中调用waite();Thread.sleep(1000);阻塞类的方法} 那么while就会检测不到cancle=true。 但如果是用interrupt()设置标志位,waite();Thread.sleep(1000)方法检测到中断(如果发起了中断,方法底层会抛出interruptException异常,并把中断标识由true改成false),所以一定不建议自己定义cancel变量检测。
调用interrupt()后,会强制将sleep,wait (阻塞的线程)的线程,将行唤醒,也就是说interrupt()后,sleep的线程会抛出异常,所以我们在run里面可以捕获这个异常。
注意:如果run()方法里面调用了抛出InterruptException异常时,如果捕获了异常,那么注意要设置中断标志位,才可结束线程

public void run() {
	while(!isInterrupted()) {
		try {
			Thread.sleep(100);//当中这个线程发起中断标志位时,会抛出异常并把中断标志位由true改成了false,可以在exception中调用interrupt()方法设置中断标志为true,那么while()条件interrupted检测到为true就结束循环,或可直接在异常中不理采
		} catch (InterruptedException e) {
			System.out.println(Thread.currentThread().getName()
					+" in InterruptedException interrupt flag is "
					+isInterrupted());
			//资源释放(比如释放锁)
			interrupt();//如果要在异常中中断异常,那么调用一次interrupt,将中断标志位设置成true,那么循环判断检测到为true,那么就会结束循环
			e.printStackTrace();
		}
	}
}

为什么sleep(), 这阻塞方法,要抛出异常并设置重新设置false,
原因 1:可以在catch中检测到有
中断标志,如果不设置false,那么while会直接检测中断为true,就会结束,有可能有资源没释放,可能造成死锁,如果将中断位设置false,让我们在catch里面可先释放资源 才决定是否要中断线程
处于死锁状态线程,不会理会中断

Runnable接口实现中断
用:Thread.currentThread().isTnterrupted() 检测中断
While(!Thread.currentThread().isTnterrupted()){}

public class TestRunnable implements Runnable{	
	@Override
	public void run() 
		String threadName = Thread.currentThread().getName();
		while(Thread.currentThread().isInterrupted()) {
			System.out.println(threadName+" is run!");
		}
		System.out.println(threadName+" interrput flag is "
				+Thread.currentThread().isInterrupted());
	}			
}
public static void main(String[] args) throws InterruptedException {
	TestRunnable testRunnable = new TestRunnable ();
	Thread endThread = new Thread(testRunnable ,"endThread");
	endThread.start();
	Thread.sleep(20);
	endThread.interrupt();
}
三、start() run()区别

Start() Run(),区别:
Start():有且仅能调用一次,启一个线程执行run()
Start()方法里面一开始会检测装态,如果已启动,那么抛异常。
Run(),不会启线程,无论调多少次都行

Jion()方法
如何保证2个方法顺序执行? 调用join()方法
Yiedld():让出cup执行权,不会让出锁

调用yield(),sleep(),wait(),notify(),对锁有何影响?
守护线程: jdk启动或设置守护线程 启动的就是守护线程,他是服务类线程,做一些后台调度和支持性工作,对内存的管理

用户线程结束后,守护线程就会结束;比如管理应用程 序的线程是守护线程,当应用执行完后,管理应用程序的守护线程也应结束。

注意:
一般在线程里面快束结的时候我们会在finally{}里面执行一释放资源操作,但是如果把一个线程改成守护线程后,finally{}里面的代码不一定会执行。
所以如果我们需要回收资源那么就不能设置成守护线程

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!