黑马程序员技术交流社区
标题:
石家庄 就业班JavaSE Day06
[打印本页]
作者:
小北京
时间:
2018-11-20 15:25
标题:
石家庄 就业班JavaSE Day06
线程:
多线程的原理:
1: 线程执行的随机性 CPU执行哪个线程是随机的,不能人为干预,
Java线程调度室抢占式的,多个线程互相抢夺
CPU的高速随机切换(本质)
多个线程抢占CPU资源
创建线程的 一种方式
:
extends Thread 继承
定义类继承Thread
重写run方法,写要执行的任务
创建子类的对象,调用.start( ) 方法开启线程
.
多线程的原理:
2
:多线程的内存 每个线程都有各自的栈内存
栈是每个线程各自的, 堆是每个线程共用的
/*Thread常用方法:
Thread(): 创建Thead对象
Thread(String threadName): 创建Thead对象并指定线程名
Thread(Runnable target): 通过Runnable对象创建Thread对象
Thread(Runnable target, String threadName): 通过Runnable对象创建对象并指定线程名
// 成员方法
void run(): 用于让子类重写, 表示该线程要执行的任务.不能直接调用
void start(): 启动线程, 即让线程开始执行run()方法中的代码
String getName(): 获取线程的名称
void setName(String name): 设置线程名称
// 静态方法
static Thread currentThread(): 返回对当前正在执行的线程对象的引用
static void sleep(long millis): 让所在线程睡眠指定的毫秒*/
创建多线程程序的第二种方式: 实现Runnable接口
建线程的第2种方式:
1
. 定义类, 实现Runnable接口
2.
重写 run() 方法, 要执行的代码(任务)
3.
创建Runnable实现类对象 (任务对象)
4.
创建Thread类对象, 在构造方法中传入Runnable实现类对象 (将任务和线程绑定)
5.
通过Thread对象调用 start() 方法启动线程
Thread和Runnable的区别:
1. 多个相同的程序代码的线程去共享同一个资源。
2. 可以避免java中的单继承的局限性。
3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和数据独立。
匿名内部类创建线程:
new 父接口/父类() {
重写方法
};
继承Thread类
实现Runnable接口
线程的安全问题:
JVM是抢占式调度, CPU在每个线程之间切换是随机的, 代码执行到什么位置是不确定的
在操作共享资源时, 由于一个线程还没有执行完, 另一个线程就来操作, 就会出现问题
如何解决:
在操作共享资源时, 让线程一个一个来执行, 不要并发操作共享变量, 就可以解决问题
解决线程安全问题方式:
1. 同步代码块
2. 同步方法
3. Lock锁机制
同步代码块: 使用 synchronized 关键字修饰的代码块, 并传入一个当作锁的对象
格式:
synchronized (锁对象) {
// 操作共享数据的代码
注意:
锁对象可以是"任意类型的一个对象"
锁对象必须是"被多个线程共享的唯一的"对象
锁对象的作用: 只让一个线程在同步代码块中执行
}
同步技术解决线程安全问题的原理:锁对象, 也称为"同步锁", "对象锁", "对象监视器"
解决线程安全问题方式2: 同步方法
同步方法: 使用 synchronized 关键字修饰的方法, 具有默认的锁对象
非静态同步方法的锁对象: this
非静态同步方法
public synchronized void method(){
可能会产生线程安全问题的代码
}
静态同步方法
public static synchronized void method(){
// 可能会产生线程安全问题的代码
}
获取一个类的字节码对象的3种方式:
1. 对象名.getClass() new RunnableImpl().getClass()
2. 类名.class RunnableImpl.class
3. Class.forName("类的全名"); Class.forName("com.itheima.test05.RunnableImpl");
字节码对象的特点:
同一个类, 他的字节码对象只有"唯一的一个"
Person
new Person() this
new Person() this
...
Person.class 只有一个
锁对象必须是多个线程共享的同一个对象
解决线程安全问题方式3: Lock锁
void lock(): 获取锁
void unlock(): 释放锁
线程间的通信:
线程的生命周期中, 有哪6种状态
锁对象, 也称为"同步锁", "对象锁", "对象监视器"
// 成员方法 (<<注意>>: 只能通过"锁对象"调用)
void notify(): 随机唤醒在同一个锁对象上的某一个处于等待状态的线程
void notifyAll(): 唤醒所有在同一个锁对象上处于等待状态的线程
void wait(): 让当前线程处于"无限等待"状态
void wait(long timeout): 让当前线程处于"计时等待"状态, 时间到或被唤醒后结束此状态
void wait(long timeout, int nanos): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态
"注意!! 以上方法只能通过锁对象调用"
Object类中wait(long timeout)和notifyAll()方法:
wait() 计时等待, 何时可以唤醒 (让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态)
notifyAll() 会唤醒什么样的线程 唤醒所有在同一个锁对象上处于等待状态的线程
wait() 和 sleep() 的区别:
1. wait会释放锁, 恢复时需要重新获取锁; sleep不会释放锁
2. wait可以被notify/notifyAll唤醒; sleep不会
3. wait要用锁对象调用; sleep要用Thread类名调用
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2