• 多线程


    	
    	1、多线程:一个应用程序有多条执行路径
    		进程:正在运行的应用程序(是系统进行资源分配和调用的独立单元,每一个进程有它自己的内存空间和系统资源)
    		线程:进程的执行单元(程序执行的任务),执行路径
    		
    		单线程:一个应用程序只有一条执行路径
    		多线程:一个应用程序有多条执行路径(一个程序执行多个任务)
    		
    		并行和并发:
    			前者是逻辑上同时发生,指在某一个时间内同时运行多个程序。
    			后者是物理上同时发生,指在某一个时间点同时运行多个程序。
    			
    		多进程的意义?
    			提高CPU的使用率
    		多线程的意义?
    			提高应用程序的使用率
    	2、Java程序的运行原理及JVM的启动是多线程的吗?
    		A:Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程,主线程去调用某个类的 main 方法。所以 main方法运行在主线程中。
    		B:JVM的启动是多线程的,它最少有两个线程启动,主线程和垃圾回收线程。
    	3、多线程的实现方案(掌握)
    		A:继承Thread类
    			1)自定义类MyThread继承Thread类
    			2)MyThread类里面重写run()
    				run+alt+/
    				为什么?
    					不是类中所有代码都需要被线程执行(方法包含 需要线程执行的代码(比较耗时的代码)),为了区分哪些代码能够被线程执行。
    				getName();	//获取线程名称(在run()方法中)
    				Thread.currentThread().getName();	//通用获取线程名称
    			3)创建对象
    				MyThread mt = new MyThread();
    			4)启动线程
    				mt.start();
    		注意:重复调用run方法是单线程
    				run()和start()的区别?
    					run():仅仅是封装被线程执行的代码,直接调用是普通方法
    					start():首先启动了线程,然后再由jvm去调用该线程的方法
    			  IllegalThreadStasteException:指非法线程状态异常
    				why?
    					两个start()相当于是mt线程被调用了两次。而不是两个线程启动。
    					解决:创建两个线程对象
    					MyThread mt2 = new MyThread();
    					mt.setName("baron");	//设置线程名称
    					mt.start();
    					mt2.start();
    		B:实现Runnable接口(常用)
    			1)自定义类MyRunnable类实现Runnable接口
    			2)重写run()方法
    			3)创建MyRunnable类对象
    			4)创建Thread类对象,并把3)步骤的对象作为构造参数传递
    		C:有了方式一为什么还有方式二?
    			解决了Java单继承带来的局限性
    			适合多个相同程序的代码去处理一个资源的情况,把线程同程序的代码,数据有分离。较好的体现了面向对象的设计思想。
    	4、线程的调度和优先级问题
                    假如我们的计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只 有得到 CPU时间片,也就是使用权,才可以执行指令。
    		A:线程的两种调度模型
    			a:分时调度:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
    			b:抢占式调度 (Java采用的是该调度方式):优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。
    		B:获取和设置线程优先级
    			a:默认是5
    			b:范围是1-10
    			c:获取线程对象优先级
    				public final int getPriority()
    					mt.getPriority();
    			d:设置对象优先级
    					mt.setPriority();
    				IllegalArgumentException:非法参数异常
    				线程优先级高仅仅表示线程获取的CPU时间片的几率高,但要在次数比较多,或者多次运行的时候才能看到比较好的效果
    	5、线程的控制(常见方法)
    		A:休眠线程
    			public static void sleep(long millis)
    				Thread.sleep(1000);	//在run()或main()方法中休息一秒
    		B:加入线程
    			public final void join()	//等待线程终止(意思是其它线程等待我执行完毕后才可执行)
    				mt.join();
    		C:礼让线程
    			public static void yield():暂停当前正在执行的线程对象,并执行其它线程。
    				Thread.yield();	//在run()方法中让多个线程的执行更加和谐,但不能靠它保证一人一次。
    		D:后台线程
    			public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程,当正在运行的线程是守护线程时,Java虚拟机退出,该方法必须在启动线程前调用。
    				mt.setDaemon(true);
    				mt2.setDaemon(true);
    		E:终止线程(掌握)
    			public final void stop():过时,但是还可以用
    				mt.stop();
    			public void interrupt():终止线程,把线程状态终止,并抛出InterruptedException
    			mt.interrupt();
    	6、线程的生命周期(参照	线程生命周期图解.bmp)
    		A:新建:创建线程对象
    		B:就绪:有执行资格,无执行权限
    		C:运行:有执行资格,有执行权限
    		D:阻塞:由于一些操作让线程处于该状态,没有执行资格,没有执行权限。一些操作可将其激活,激活后处于就绪状态。
    		E:死亡:线程对象变成垃圾,等待被回收
    	7、电影院卖票程序的实现
                    某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。
    		A:继承Thread类
    		B:实现Runnable接口
    	8、电影院卖票程序出问题
    		A:为了更符合真实的场景,加入了休眠100毫秒。
    		B:卖票问题
    			a:同票多次
    			b:负数票
    	9、多线程安全问题的原因(也是我们以后判断一个程序是否有线程安全问题的依据)
    		A:是否有多线程环境
    		B:是否有共享数据
    		C:是否有多条语句操作共享数据
    	10、同步解决线程安全问题
    		A:同步代码块
    			synchronized(对象) {
    				需要被同步的代码;
    			}
    			
    			这里的锁对象可以是任意对象。
    			
    		B:同步方法
    			把同步加在方法上。
    			
    			这里的锁对象是this
    			
    		C:静态同步方法
    			把同步加在方法上。
    			
    			这里的锁对象是当前类的字节码文件对象(反射再讲字节码文件对象)
    			
    			例子:
    				@Override
    					public void run() {
    						while (true) {
    							if(x%2==0){
    								synchronized (SellTicket.class) {	//例子B换成this
    									if (tickets > 0) {
    										try {
    											Thread.sleep(100);
    										} catch (InterruptedException e) {
    											e.printStackTrace();
    										}
    										System.out.println(Thread.currentThread().getName()
    												+ "正在出售第" + (tickets--) + "张票 ");
    									}
    								}
    							}else {
    					
    								sellTicket();
    						
    							}
    							x++;
    						}
    					}
    					
    					private static synchronized void sellTicket() {
    						if (tickets > 0) {
    						try {
    								Thread.sleep(100);
    						} catch (InterruptedException e) {
    								e.printStackTrace();
    						}
    						System.out.println(Thread.currentThread().getName()
    									+ "正在出售第" + (tickets--) + "张票 ");
    						}
    				}
    				}
    		D:同步的前提
    			多个线程
    			多个线程使用的是同一个锁对象
    			
    		E:同步的弊端:
    			当线程较多时,因为每个线程都会去判断同步上的锁,很耗资源,无形中降低程序运行效率
    	11、回顾以前的线程安全的类
    		A:StringBuffer
    		B:Vector
    		C:Hashtable
    		D:如何把一个线程不安全的集合类变成一个线程安全的集合类
    			用Collections工具类的方法即可。
    			// Vector是线程安全的时候才去考虑使用的,但是我还说过即使要安全,我也不用你
    			// 那么到底用谁呢?
    			// public static  XXXX synchronizedXXXX(XXXX XXXX)
    			List list1 = new ArrayList();// 线程不安全
    			List list2 = Collections.synchronizedList(new ArrayList()); // 线程安全
  • 相关阅读:
    把本地的jar包安装到maven库中
    mybatis 查询
    freemarker
    python——线程相关
    【python-sql】sql操作时遇到的坑
    专项测试——移动app安装包检测
    【Android端 adb相关】adb相关总结
    for 语句
    Python2.x与3​​.x版本区别
    Python 运算符
  • 原文地址:https://www.cnblogs.com/zhanwang/p/7683782.html
Copyright © 2020-2023  润新知