线程
一,程序,进程,线程
1,程序:指令集,静态概念
2,进程:操作系统,调度程序,动态概念
3,线程:在进程内的多条执行路径,多线程并发执行可以提高程序效率。
二,多线程并行与并发
并行:两个任务同时运行(需要多核CPU)。
并发:两个任务都请求运行,处理器安排轮流运行。
三,JVM运行原理与多线程
1,Java命令会启动java虚拟机,启动JVM,等于启动一个进程,该进程会自动启动“主线程”,紧接着主线程去调用某类的main方法。
2,JVM启动至少会启动垃圾回收线程和主线程,所以JVM是多线程。
四,多线程实现
1>继承Thread
1,->定义类继承Thread
2, -->重写run方法
3, --->把任务写在run方法中
4,---->创建线程对象,调用start()开启线程
5, ----->开启新线程,内部执run方法
public class ThreadDemo{
public static void main(String[] args){
MyThread th = new MyThread();
th.start();
}
class MyThread extenda Thread{
public void run(){
System.out.println("我要执行多线程!");
}
}
}
2>实现runnable
1,->定义类实现Runnable接口
2,-->实现run方法
3,--->把任务写在run方法中
4,---->创建自定义的Runnable的子类对象
5,----->创建Thread对象,传入Runnable
6,------>调用start()开启新线程,内部调用Runnable方法
eg:
public class RunnableDemo{
public static void main(Strig[] main){
MyRunnable mr = new MyRunnable();
Thread th = new Thread(mr);
th.start();
}
class MyRunnable implements Runnable{
System.out.println("我要执行多线程!");
}
}
五,获取与设置名字
1,获取名字:通过getName()方法获取线程对象的名字.
2,设置名字:通过setName()方法、构造函数传入String类型的名字.
六,主要方法
1,currentThread():获取当前线程对象。
2,sleep(毫秒、纳秒):控制当前线程休眠若干秒。(1秒 = 1000毫秒 = 1000000000纳秒)
3,join():当前线程暂停,等待指定的线程执行结束后,当前线程再继续执行。
4,setDaemon():设置一个线程为守护线程,该线程不会单独执行,当其他非守护线程都执行结束后,自动退出
5,yield:让出CUP
6,setPriority():设置线程优先级
七,同步代码块
1>运用场景:
当线程并发,有多个代码同时执行时,需要某一段代码执行过程中CPU不要切换到其他线程工作,就时需要同步代码块。
如果两段代码是同步的,那么同一时间只能执行一段,在一段代码没执行结束前,不会执行另一段代码。
2>同步代码块:
使用synchronized关键字,添加一个锁对象(任意)来定义一段代码,这就是同步代码块。
多个同步代码块如果使用相同的锁对象,那么他们就是同步的。
3>同步方法:
使用synchronized关键字,修饰一个方法,该方法中所有的代码都是同步的。
非静态的同步方法的锁对象是this。
而静态的同步方法的锁对象是该类的字节码对象(类名.class)。
八,单例设计模式
保证类在内存中只有一个对象。
1>设计方式
1,控制类的创建,不让其他类来创建本类的对象。
2,在本类中定义一个本类的对象。
3,提供公共的访问方式
饿汉式:
class Singleton{
//1,私有构造函数
private Singleton(){}
//2,创建本类对象
private static Singleton s = new Singleton();
//3,对外提供公共的访问方式
public static Singleton getInstance(){
return s;
}
public static void print(){
System.out.println("123");
}
}
懒汉式:
class Singleton{
//1,私有构造方法
private Singleton(){}
//2,声明一个引用
private static Singleton s ;
//3,对外提供公共的访问方式
public static Singleton getInstance(){
if(s == null){
s = new Singleton();
}
return s;
}
public static void print(){
System.out.println("123");
}
}
2>饿汉式与懒汉式区别
1,饿汉式:内存空间换取访问时间,多线程访问时饿汉式不会创建多个对象。
2,懒汉式:访问时间换取内存空间,多线程访问时懒汉是可能创建多个对象。
九,主要方法
1,Runtime类,getRuntime():返回与当前Java应用程序相关的运行时对象。
2,Timer类,schedule():安排在指定的时间执行指定的任务。
十,线程间的通信
1>应用环境
多个线程并发执行时,默认时CPU是随机切换的,需要它有规律的执行时就应用通信。
2>两个线程间的通信
1,使线程等待,调用wait();
2,使唤醒等待的线程,调用notifyAll();
这两个方法必须在同步代码块中执行,并且使用同步锁对象来调用。
3>多个线程间的通信
1,notify()方法是随机唤醒一个线程。
2,notifyAll()方法是唤醒所有线程。
用notifyAll()通知所有线程,用while来反复判断条件
4>线程间的通信注意事项
1,在同步代码块中,使用哪个锁对象,该锁对象就调用wait()方法。
2,sleep()方法与wait()方法的区别:
a.sleep方法必须传入参数,wait方法可传可不传。
b.sleep方法在同步代码块中不释放锁。
wait方法在同步代码块中释放锁。
十一,互斥锁
1、同步: 使用ReentrantLock类的lock()和unlock()方法进行同步。
2、通信: 使用ReentrantLock类的newCondition()方法获取Condition对象;
需要等待的时候使用Condition的await()方法,唤醒使用signal()方法;
不同的线程使用不同的Condition,容易区分不同的线程。
十二,线程生命周期
[非原创图,未知原作者,若有追究可侵删]
十三,简单工厂模式
1>概述
它定义一个具体的工厂类负责创建一些类的实例,又叫静态工厂方法模式。
2>优缺点
优点:客户端不需要再负责对象的创建,明确了各个类的职责。
缺点:简单工厂模式负责所有对象的创建,若有新的对象增加,或者某些对象的创建方式不用,就需要不断修改工厂类,不利于后期维护