1、多线程总结:1,进程和线程的概念。|-进程:正在运行的程序。是一个应用程序的内存中的一片空间,是由相应的系统进行分配的。|-线程:就是负责进行执行的。也是由相应的系统进行分配,一个进程中至少有一个线程,如果有多个线程这个程序就成为多线程程序。2, jvm 中的多线程体现。|-主线程,垃圾回收线程,自定义线程。以及他们运行的代码的位置。主线程:执行的是主函数中的线程。垃圾回收线程:执行的是对堆内存进行内存释放的代码。自定义线程:3,什么时候使用多线程,多线程的好处是什么?创建线程的目的?|-当需要多部分代码同时执行的时候,可以使用。好处:可以实现多部分代码同时执行,提高了用户的体验, (但是不能
2、提高程序的效率)目的:是为了开辟一个执行路径执行指定的代码,让其和其他代码同时运行。4,创建线程的两种方式。|-继承 Thread|-步骤1,继承 Thread 类2,复写 run 方法,将线程要运行的任务代码存储到 run 方法中3,创建 Thread 类的子类对象4,调用 start 方法开启线程并调用 run 方法(开启的同时调用)|-实现 Runnable|-步骤1,定义类实现 Runnable 接口2,覆盖该接口中的 run 方法,先建立实现类的对象,将线程任务封装成对象3,通过 Thread 类创建线程对象4,将实现 Runnable 类的实现类的对象作为参数传递给 Thread
3、类的构造函数,将run 方法所属的对象传递给线程,让线程去运行指定对象的 run 方法。5,调用 Thread 类的 start 方法开启线程,并运行 run 方法。|-两种方式的区别?Runnable 接口的出现将线程要运行的任务进行单独的对象的封装,降低了线程对象和线程任务的耦合性,避免了单继承的局限性。5,线程的 5 种状态。对于执行资格和执行权在状态中的具体特点。|-被创建:|-运行:有,有|-冻结:无,无|-临时阻塞:有,无|-消亡:无,无-6,线程的安全问题。|-安全问题的原因:1,多个线程在处理同一个共享数据2,线程任务代码中有多个语句在操作这个共享数据3,这么多条操作共享数据的
4、语句被多个线程分开执行,也就是说在一个线程执行这些语句的过程中,其他线程参与了运算导致数据的错误。|-解决的思想:将多条操作共享数据的代码进行封装,在某一时刻,只能有一个线程在内运行,在运行期间其他的线程线程都进不来,只有这个线程运行完其他线程才有机会执行其中的内容|-解决的体现:synchronized|-同步的前提:但是加上同步还出现安全问题,就需要用前提来思考。必须有多个线程,而且使用的是同一个锁|-同步的两种表现方法和区别:|-同步的好处和弊端:好处:解决的了多线程的安全问题弊端:降低了效率,容易出现死锁。|-单例的懒汉式。class Singleprivate static Sing
5、le s = null;private Single()public static Single getInstance()if(s=null)synchronized(Single.class)if(s=null)/ 0 1s = new Single();return s;懒汉式:当多线程并发访问时,会出现多线程的安全问题。无法在保证多线的唯一性。在获取对象的方法上加上同步关键字,让该方法具备同步性,就可以解决线程安全问题。但是,性能会降低。解决性能问题的方式:通过双重判断的形式。这样做的好处就是减少了判断锁的动作。相对提高了性能。|-死锁。原理:同步的嵌套同步中有同步,而锁不同。-7,线
6、程间的通信。等待/唤醒机制。|-概念:多个线程,不同任务,处理同一资源。 |-等待唤醒机制。使用了锁上的 wait notify notifyAll. |-生产者/消费者的问题。并多生产和多消费的问题。 while 判断标记。用 notifyAll唤醒对方。 |-JDK1.5 以后出现了更好的方案,Lock 接口替代了 synchronized Condition 接口替代了 Object 中的监视方法,并将监视器方法封装成了 Condition和以前不同的是,以前一个锁上只能有一组监视器方法。现在,一个 Lock 锁上可以多组监视器方法对象。可以实现一组负责生产者,一组负责消费者。 |-wa
7、it 和 sleep 的区别。 1,wait 必须在同步中,而 sleep 不一定;2,在同步中Wait:释放执行权,会释放锁Sleep:释放执行权,不会释放锁3,sleep 必须指定睡眠时间,而 wait 不一定,可以被 notify 唤醒。8,停止线程的方式。|-原理:让 run 方法结束。 Run 方法中有循环结构的语句,所以想要让 run 方法停止:控制循环控制循环条件,控制之一就是定义 boolean 型标记。当线程处于了冻结状态是无法去执行标记的,就无法结束,这是需要 interrupt 强制让其运行,去执行标记,然后结束 run 方法。|-表现:-中断。9,线程常见的一些方法。|
8、-setDaemon():守护程序(后台程序)当非守护程序(前台程序)都结束时,无论后台程序是否运行完毕,都会结束。|-join();当有线程调用 join 方法时,主线程会暂时释放执行资格和执行权,当此此线程执行完毕,主线程在重新获取执行资格和执行权。|-优先级:setPrioity();设置优先级。(1-10) 数字越大优先级越高,一般是(1,5,10), 因为这样区别明显。MAX_PRIORITY 最大优先级(10)MIN_PRIORITY 最小优先级(1)NORM_PRIORITY 默认优先级 (5)|-yield();暂停正在执行的线程,会释放执行权。|-在开发时,可以使用匿名内部类
9、来完成局部的路径开辟。Thread 类中 run()和 start()方法的区别如下:run()方法:在本线程内调用该 Runnable 对象的 run()方法,可以重复多次调用;start()方法:启动一个线程,调用该 Runnable 对象的 run()方法,不能多次启动一个线程;package com.ljq.test;public class ThreadTest /* 观察直接调用 run()和用 start()启动一个线程的差别 * * param args* throws Exception*/public static void main(String args)Thread
10、thread=new ThreadDemo();/第一种/表明: run()和其他方法的调用没任何不同,main 方法按顺序执行了它,并打印出最后一句/thread.run();/第二种/表明: start()方法重新创建了一个线程,在 main 方法执行结束后,由于 start()方法创建的线程没有运行结束,/因此主线程未能退出,直到线程 thread 也执行完毕.这里要注意,默认创建的线程是用户线程(非守护线程)/thread.start();/第三种/1、为什么没有打印出 100 句呢?因为我们将 thread 线程设置为了 daemon(守护)线程,程序中只有守护线程存在的时候,是可以
11、退出的,所以只打印了七句便退出了/2、当 java 虚拟机中有守护线程在运行的时候,java 虚拟机会关闭。当所有常规线程运行完毕以后,/守护线程不管运行到哪里,虚拟机都会退出运行。所以你的守护线程最好不要写一些会影响程序的业务逻辑。否则无法预料程序到底会出现什么问题/thread.setDaemon(true);/thread.start();/第四种/用户线程可以被 System.exit(0)强制 kill 掉,所以也只打印出七句thread.start();System.out.println(“main thread is over“);System.exit(1);public static class ThreadDemo extends ThreadOverridepublic void run() for (int i = 0; i 100; i+) System.out.println(“This is a Thread test“+i);