Java学习笔记之线程

时间:2022-05-17 11:57:21
所谓线程就是进程的执行路径,执行单元,为进程就是正在执行的应用程序,顾名思义,多进程就是一个程序的多个执行单元,执行路径。
多线程的两种方案
继承Thread类(查看api简单介绍Thread类):
实现Runable接口:
多线程的几个问题:
A:启动线程用的是哪个方法
start()
B:start()和run()的区别
start():1.开启线程 2.执行run()方法里面的代码
run():执行的是线程里面执行的代码,并不会开启线程
C:为什么要重写run()
因为每个线程需要执行的代码都是都是不一样的,
我们需要将每个线程自己独立执行的代码写到run()方法中执行
D:线程可以多次启动吗
不可以,一个进程只能启动一次,随后与其他进程一起抢占CPU的资源
线程的调度和控制
线程休眠(Thread.sleep(毫秒值))
线程名称(setName(),getName();)
线程的调度及优先级setPriority(10)(注意默认值是5,区间在1-10之间)
线程优先级:说白了就是设置你抢占cpu执行权抢占到的概率,规定了线程执行的顺序
多线程案例(两种方式实现,睡一会出现线程安全问题):
A.继承Thread卖票
B.实现Runnable卖票(睡一会出现线程安全问题)

问题:
按照真实的情景加入了延迟,确发现出现了这样的两个问题:
A:相同的票卖了多次
CPU的一次操作必须是原子性的(操作是CPU执行一次就可以直接完成的)
B:出现了负数的票
随机性和延迟导致的
出现上面的问题称为线程安全问题。
public class MyThread implements Runnable{
int ticket = 100;
Object obj = new Object();

public void run(){
while(true){
// synchronized (obj) {
if(ticket>0){
try{
Thread.sleep(100);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "正在出售第" + ticket-- + "张票");
}
// }
}
}
}
判断线程安全问题:
A:是否是多线程环境
B:是否有共享数据
C:是否有多条语句操作共享数据
为了解决线程安全问题引入了同步代码块(线程安全执行效率就低)
synchronized(对象) {
需要被同步的代码。
}
对象被称为线程的锁,对于多线程,所必须保证是同一把锁;与同步代码块相一致的解决方法
有同步方法,和静态同步方法,他们的锁分别为此类的对象this和本类的字节码文件对象:类名
class。
JDK5的Lock锁,我们之前造的所有的锁都没有手动释放锁
static Lock lock = new ReentrantLock();
枷锁:lock.lock();
释放锁:lock.unlock();
可以让我们明确的知道在哪里加锁和释放锁。
依然写一个卖票的demo,用lock枷锁释放锁,
为了保证我们创建的锁一定会被释放,用一下代码进行改进
try{....}finally{.....}

死锁问题
同步嵌套,锁里面套了一个锁,出现同步嵌套
(简单介绍,要求大家以后写的时候需要注意)

线程等待和唤醒机制(案例演示:waitThread,NotifyThread,MyLock,Test)
锁对象调用wait()锁对象调用notify()

注意:
wait和sleep的区别
线程等待,在等待的同时释放锁,而sleep()方法在执行的过程中是不会释放锁的