欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

线程使用

程序员文章站 2022-05-18 10:03:14
...

1. 定义

1.1定义线程有两种方式
继承Thread类
实现Runnable接口(因Java单继承,推荐使用实现接口的方式)
1.2语法格式
继承Thread类

// 线程入口方法
@Override
   public void run() {
   }
 }

实现Runnable接口

// 线程入口方法
@Override
   public void run() {
   }
 }

2. 创建和启动
线程启动是通过调用线程类的start()方法,使线程进入就绪状态。CPU时间片到来,则线程真正执行run方法。
【示例】
继承Thread类

//初始化线程对象
Thread t = new PrintThread("打印线程"); 
//正式启动线程
t.start();

实现Runnable接口

//初始化一个Runnable接口实现类的对象
PrintRunnable pr = new PrintRunnable();
//pt本身没有线程开启的能力,需要依附到Thread中才能开启线程
Thread pt = new Thread(pr, "打印线程");
// 开启线程执行
pt.start();

3. 生命周期
线程的生命周期存在五个状态:新建、就绪、运行、阻塞、死亡
新建:采用new语句创建完成
就绪:执行start后
运行:占用CPU时间
阻塞:执行了wait语句、执行了sleep语句和等待某个对象锁,等待输入的场合
终止:执行完run()方法
线程使用
三. 线程控制
线程控制,即通过API控制线程状态之间的转换。
线程使用
1. 优雅的结束
API提供了线程结束的方法:stop()方法。但是,该方法使用的过程中经常出现问题,会造成程序关闭延迟甚至死锁。
所以想要优雅的结束,可以通过设置标志位,来控制线程是否继续运行。

线程同步

所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法。
1. 线程同步的必要性
保证多线程安全访问竞争资源。
为了防止多个线程访问一个数据对象时,对数据造成的破坏。

【示例】
银行卡取钱,防止多个家庭成员使用同一个账户同时取款造成的存款余额不准问题。(同步与不同步对比)
2. 线程同步原理
上例可以看到我们在实现线程同步的时候,使用了synchronized关键字。该关键字修饰在方法上相当于对该方法加了锁。一个线程访问方法的时候需要先获得锁,然后才能执行该方法。此时,如果其他线程来了,发现锁已经被占用,则在方法调用处等待,直到锁被释放,再去竞争锁。获得锁,则执行该方法,否则,继续等待。
2.1线程锁
每个Java对象都有一个内置锁,有且只有一个。
当程序执行到非静态的synchronized同步方法时,(如果锁没被其他线程占用)自动获得该方法所属对象的锁。
不只是可以修饰在方法上同步方法,也可以对代码块加锁。
程序执行的时候,退出同步块或同步方法则释放锁。
【注意】
不必同步类中所有的方法,根据需要进行同步。
线程sleep睡眠时,它所持的锁不会释放。
线程可以获得多个锁。
同步损害并发性,应该尽可能缩小同步范围。

Lock

Lock和synchronized均是为了解决线程同步问题 ,Lock相对于synchronized的功能更多、使用更灵活、更面向对象。

【使用】
private Lock lock = new ReentrantLock();
public void take(){
lock.lock();
//同步部分
lock.unlock();
}

相关标签: Java 代码