(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟.
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)好好活就是做有意义的事情.
(8)亡羊补牢,为时未晚
(9)科技领域,没有捷径与投机取巧。
(10)有实力,一年365天都是应聘的旺季,没实力,天天都是应聘的淡季。
(11)基础不牢,地动天摇
(12)写博客初心:成长自己,辅助他人。当某一天离开人世,希望博客中的思想还能帮人指引方向.
(13)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~
线程与进程理论知识入门
文章目录
1.多线程与Android线程性能优化1
1.1APP线程的概念
1.2基础概念
1.2.1CPU核心数和线程数的关系
(1)主线程的概念
无论是Android与Java都会有一个主线程main_thread,主要是用于处理用户的一些操作。如果要加载图片的话,必须要启动一个线程,这个线程就是工作线程work_thread.
(2)六个核心数举例
-
以前,单核。一个核心数是对应一个线程的。六个核心是6个线程。
-
现在多核,引入了一个技术,叫超核心技术,一个核心与线程数就是1:2的关系。六个核心数就=6*2=12个线程。
-
Android处理器
Android是ARM32. ARM64,还有X86,x64。
1.2.2CPU时间片轮转机制
一个进程至少一个线程或多个线程,如果一个进程,还有一个线程没有挂掉,没有杀掉,进程还存活。意思是进程需要依附于线程的存活而存活。反过来说线程是依附于我们的进程的。
进程A {线程一,线程二,线程三…}
进程B {线程一}
即进程B如果还有一个线程存活,那它依然还存活。
进程C{}
它里面没有线程了,进程就挂掉了。
(1)操作系统调度执行,会通过处理器CPU,再到单核线程一,执行线程,如果有一万个线程,切换就太慢了,就会很卡。CPU切换不过来了,这时候就慢下来了。
(2)超线程技术里边儿就会有多个CPU核心调度多个线程。多个CPU看能力的话,主要是看主频与睿频。
(3)线程切换时,线程的状态必须是可执行的。
(4)线程切换,如果线程多的话,是很耗性能的。
(5)CPU时间片转转机制:采用了,一种算法,这种算法叫做RR调度。很耗性能。
1.2.3什么是进程和线程
(1)进程:操作系统所管理的最小单元。
(2)线程:是CPU调度的最小单元。
(3)进程>线程
(4)任务管理器只管理我们的进程,CPU只管理我们的线程。
1.2.4澄清并行和并发
1.2.4.1并发
(1)指应用能够交替执行不同的任务,比如单CPU核心下执行多线程并非是同时执行多个任务,如果你开两个线程执行,就是在你几乎不可能察觉到的速度不断去切换这两个任务,已达到"同时执行效果",其实并不是的,只是计算机的速度太快,我们无法察觉到而已.
(2)解释:10秒钟,我服务器的吞吐量,十秒钟,多少车流量,多少车跑过去。
1.2.4.2并行
(1)指应用能够同时执行不同的任务,例:吃饭的时候可以边吃饭边打电话,这两件事情可以同时执行
(2)解释:四个跑道
1.2.4.2两者区别
一个是交替执行,一个是同时执行.
1.2.5高并发编程的好处与意义和注意事项
(1)6核12线程,平衡使用我们的线程。即不让CPU执行太多线程造成过累,让其调度执行的线程处在合理的范围之内。
(2)高并发编程:(不要让CUP过累)
(3)6核12线程
A进程里面(new Thread() 1000次 每一次都会开辟栈空间,至少有1MB,最后将消耗1GB内存,)
1.3认识Java里的线程
1.3.1Java里的程序天生就是多线程的,那么有几种启动线程的方式?
启动线程的3种方式:
private static class WorkerThread implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("do work Worker Thread");
Thread.sleep(2000);
return "run success";
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//1.new Thread().start()
//2.new Thread(new SelfRunable()).start();
//3.有返回值,任务不能运行,需要寄托Thread运行.
WorkerThread workerThread = new WorkerThread();
FutureTask<String> futureTask = new FutureTask<>(workerThread);
new Thread(futureTask).start();
System.out.println(futureTask.get());
}
(1)FutureTask类实现了RunnableFuture接口,RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
(2)事实上,FutureTask是Future接口的一个唯一实现类。
(3)要new一个FutureTask的实例,有两种方法
1.3.2有开始就有结束,怎么样才能让Java里的线程安全停止工作呢?
1.4对Java里的线程再多一点点认识
1.4.1线程常用方法和线程的状态
1.4.1.1深入理解run()和start()
(1)Thread类是Java里对线程概念的抽象,可以这样理解:我们通过new Thread()其实只是new出一个Thread的实例,还没有操作系统中真正的线程挂起钩来。只有执行了start()方法后,才实现了真正意义上的启动线程。
(2)start()方法让一个线程进入就绪队列等待分配cpu,分到cpu后才调用实现的run()方法,start()方法不能重复调用。
(3)而run方法是业务逻辑实现的地方,本质上和任意一个类的任意一个成员方法并没有任何区别,可以重复执行,可以被单独调用。
1.4.1.2其他的线程方法
(1)yield()方法:使当前线程让出CPU占有权,但让出的时间是不可设定的。也不会释放锁资源,所有执行yield()的线程有可能在进入到可执行状态后马上又被执行。
(2)join方法:把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。
(3)wait()/notify()/notifyAll()
1.4.1.3停止一个线程
1.4.1.3.1stop停止线程
(1)属暴力行为,永不使用.
1.4.1.3.2 和谐方式
(1)想办法控制run()方法执行完毕.
(2)第一版无法停止下来
public class ThreadTest1{
private static class UseThread extends Thread{
@Override
public void run() {
String name = Thread.currentThread().getName();
while (true){
System.out.println(name + "=== is run");
}
}
}
public static void main(String[] args) throws InterruptedException {
UseThread useThread = new UseThread();
useThread.start();
Thread.sleep(1000);
useThread.interrupt();//发起终断信号,如果能够停止下来,和暴力有什么区别,此处是停不下来的。
}
}
(3)和谐的停止方法
private static class UseThread extends Thread{
@Override
public void run() {
String name = Thread.currentThread().getName();
while (!isInterrupted()){//isInterrupted()默认是false
System.out.println(name + "=== is run state: " + isInterrupted());
}
System.out.println(name + "while end flag: " + isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
UseThread useThread = new UseThread();
useThread.start();
Thread.sleep(1000);
useThread.interrupt();//发起终断信号
}
(4)实现了Runable接口的线程
public class ThreadTest3 {
private static class UseThread implements Runnable{
@Override
public void run() {
String name = Thread.currentThread().getName();
while (!Thread.currentThread().isInterrupted()){
System.out.println(name + "=== is run state: " + Thread.currentThread().isInterrupted());
}
System.out.println(name + "while end flag: " + Thread.currentThread().isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
UseThread useThread = new UseThread();
Thread t = new Thread(useThread);
t.start();
Thread.sleep(1000);
t.interrupt();//发起终断信号
}
}
1.4.1.4如何做到让线程顺序执行?
使用join()来控制,让t2获取执行权力,即先执行完t1,然后再跑t2.能够做到顺序执行。
public class ThreadJoinTest extends Thread{
public ThreadJoinTest(String name){
super(name);
}
@Override
public void run() {
for (int i=0; i < 100; i++){
System.out.println(this.getName() + ":" + i);
}
}
}
public class JoinTest {
public static void main(String[] args) throws InterruptedException {
ThreadJoinTest t1 = new ThreadJoinTest("雄霸");
ThreadJoinTest t2 = new ThreadJoinTest("张三");
t1.start();
/*
join的意思是使得放弃当前线程的执行,并返回对应的线程,例如下面代码的意思是:
程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权,并返回t1线程继续执行直到
t1执行完毕,所以结果是t1线程执行完成之后,才到主线程执行,相当于在main线程中同步t1线程,t1
执行完了,main线程才有执行的机会。
*/
t1.join();//让t2获取执行权
t2.start();
}
}
1.4.1.5多线程中的并行和并发是什么?
(1)四个车道,四辆车并行的走,就是并行。
(2)四个车道中,5秒钟多少的车流量,多少的吞吐量.
1.4.1.6Java中是否可以指定的CPU去执行某个线程?
如:A、B、C三个线程
答:不能,Java是做不到的,唯一能够去干预的就是C语言调用内核的API去指定才行。
1.4.1.7在项目开发过程中,你会考虑Java线程优先级吗?
答:不会考虑优先级,为什么呢?
(1)因为线程优先级很依赖于系统的平台,所以这个优先级无法对号入座,无法做到你想象中的优先级,属于不稳定,有风险。
(2)因为某些开源框架,也不可能依靠线程优先级来,设置自己想要的优先级顺序,这个是不可靠的。
1.5 线程的状态
1.6 主线程挂守护线程跟着挂
package com.gdc.threadlib;
public class DaemonThread {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(){
@Override
public void run() {
for(int i = 0 ; i < 50; i++){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + "---" + i);
}
}
};
t.setDaemon(true);//设置了守护线程
t.start();
//1.主线程是为了等Thread t 1秒钟,然后主线程结束
Thread.sleep(30);
//2.走到这里,代表主线程结束,不管t线程有没有结束,t线程都必须结束,因为t线程是守护线程,守护了main线程
//3.守护即依附,主线程结束,依护于主线程的子线程必须结束。
//4.如果不设置成守护线程,会让主线程一直等Thread t,只有Thread t执行完,主线程才能执行完成。
}
}
1.7sleep和wait有什么区别?
(1)sleep是休眠,等休眠时间一过,才有执行权。注意:只是有资格了,并不代表马上就会被执行。什么时候又执行起来,取决于操作系统调度。
(2)wait是等待,需要人家来唤醒,唤醒后,才有执行权的资格。
含义的不同:sleep无条件可以休眠,wait是某些原因与条件需要等待一下(资源不满足)。
1.8Java中能不能中断线程的执行。
(1)虽然提供了stop等函数,但是此函数不推荐使用,为什么?因为这种暴力的方式,很危险,例如:下载图片15kb,只下载了4kb等
(2)我们可以使用interrupt来处理线程的停止,但是注意interrupt()只是协作式的方式,并不能绝对保证中断,并不是抢占式的。
public class ThreadTest4 {
private static class UseThread implements Runnable{
@Override
public void run() {
String name = Thread.currentThread().getName();
while (!Thread.currentThread().isInterrupted()){
System.out.println(name + "=== is run state: " + Thread.currentThread().isInterrupted());
try {
Thread.sleep(300);//清除中断标记
} catch (InterruptedException e) {
e.printStackTrace();
//sleep()会把终断信号清除,就会导致线程停止不下来,此时使用和谐的方式也停止不了线程。
//因此想要和谐的终止线程,则需要在此再次发出中断信号
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().getName() +
"catch interrupt " + Thread.currentThread().isInterrupted());
}
}
System.out.println(name + "while end flag: " + Thread.currentThread().isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
UseThread useThread = new UseThread();
Thread t = new Thread(useThread);
t.start();
Thread.sleep(1000);
t.interrupt();//发起终断信号
}
}
1.9如何让出当前线程的执行权?
答:调用yield()方法,只在JDK某些实现上才能看到,是让出执行权。
1.10sleep,wait哪个方法才会清除中断标记?
(1)即sleep()与wait()方法哪个方法会使interrupt()发出的中断标记不起作用?
(2)答案是sleep()方法,sleep()方法在抛出异常的时候,捕获异常之前,就已经清除。
2.打赏鼓励
感谢您的细心阅读,您的鼓励是我写作的不竭动力!!!