java之多线程基础

    多线程

1. 主线程:执行主(main)方法的线程,叫做主线程
程序执行的入口是main方法
程序从main方法开始执行,从上到下依次执行,这个程序就是一个单线程的程序

java程序进入到内存中执行,就是一个进程
JVM(java虚拟机),会先执行程序的入口main方法
JVM会找操作系统开辟一条java程序通向cpu的路径
cpu通过这个路径就可以执行main方法
这个路径有一个名字,叫做主线程(main线程)

2. 实现多线程的第一种方式:将类声明为 Thread 的子类

实现步骤:
1> 创建一个Thread类的子类
2> 重写Thread类中的run方法,设置线程任务(开启线程要干什么事情)
3> 创建Thread类的子类对象
4> 调用Thread类中的方法start方法,开启一个新的线程执行run方法

3. 获取线程的名称:
1> 可以通过Thread类中的方法getName获取
String getName() 返回该线程的名称。
2> 通过Thread类中的方法,先获取当前正在执行的线程,在通过线程中的方法getName获取线程名称
static Thread currentThread() 返回对当前正在执行的线程对象的引用。

设置线程的名称
1> 使用Thread类中的方法setName
void setName(String name) 改变线程名称,使之与参数 name 相同。
2> 创建带参数构造方法,参数传递线程的名称;方法中调用父类的带参数构造方法,把名称传递过父类,让父类帮子类起名字
Thread(String name) 分配新的 Thread 对象。

4. start方法:
使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
结果是两个线程并发地运行;当前线程(执行main方法的线程,主线程)和另一个线程(执行其 run 方法的线程,Thread-0,...)。
多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

Thread类中的方法sleep
static void sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
让程序睡觉,睡醒了继续执行

5. 创建多线程的第二种方式:实现Runnable接口

Thread类中的构造方法:传递的是Runnable接口的实现类对象
Thread(Runnable target) 分配新的 Thread 对象。

实现步骤:
1> 定义Runnable接口的实现类
2> 重写Runnable接口中的run方法,设置线程任务
3> 创建Runnable接口的实现类对象
4> 创建Thread类对象,构造方法中传递Runnable接口的实现类对象
5> 调用Thread类中的方法start,开启新线程,执行run方法

实现Runnable接口方式创建多线程的好处:
1> 避免了单继承的局限性.实现了接口还可以继承其它的类
2> 把设置线程任务和开启线程进行了解耦,增强程序的扩展性
实现Runnable接口,重写run方法:目的就是设置线程任务
把线程的运行交个Thread类

6. 多线程的匿名内部类的创建方式:
匿名:创建的对象没有名字
内部类:写在其他类内部的类

格式:
new 父类/接口(){
重写父类/接口中的方法;
};
匿名内部类的作用:把定义子类,重写父类/接口的方法,创建子类对象合成一步完成
匿名内部类的结果:就是一个子类对象


7. 线程安全问题
1> 解决线程安全问题的第一种方式:使用同步代码块
格式:
synchronized(锁对象){
可能出现线程安全问题的代码(访问了共享数据的代码)
}
注意:
必须要保证多个线程使用的锁对象是同一个锁对象

2> 解决线程安全问题的第二种方式:使用同步方法
就是一个方法,在方法上添加一个关键字synchronized修饰

格式:
修饰符 synchronized 返回值类型 方法名(参数列表){
可能出现线程安全问题的代码(访问了共享数据的代码)
}
* 静态的同步方法
* 静态的同步方法锁对象不能是this,this创建对象之后才会出现的
* 静态优先于非静态加载到内存中
* 静态方法的锁对象是本类的class属性(class文件对象,反射)
* RunnableImpl.class

3> 解决线程安全问题的第三种方式:Lock锁,JDK1.5之后出现的新特性
java.util.concurrent.locks.Lock接口
接口中的方法:
void lock() 获取锁。
void unlock() 释放锁。
Lock接口的实现类
java.util.concurrent.locks.ReentrantLock类 implements Lock接口

使用步骤:
1> 在成员位置创建一个Lock接口的实现类对象ReentrantLock
2> 在可能会出现线程安全问题的代码前,调用Lock中方法lock获取锁对象
3> 在可能会出现线程安全问题的代码后,调用Lock中方法unlock释放锁对象

原文地址:https://www.cnblogs.com/youyouxiaosheng-lh/p/8343317.html