一、 创建线程的方法
(一)继承线程类java.lang.Thread
1、继承Thread类,重写run方法
public class Task extends Thread{
public Task(){}
@Override
public void run(){
// 主要逻辑
}
}
2、创建对象,启动线程
// 创建线程子类对象
Task t = new Task();
// 启动线程
t.start();
(二)用Runnable子类对象来创建java.lang.Thread对象
1、实现接口Runnable的run方法
public class Task implements Runnable{
public Task(){}
@Override
public void run(){
// 主要逻辑
}
}
2、用子类对象创建Thread对象
// 创建线程对象
Thread t = new Thread(new Task());
// 启动线程
t.start();
二、Thread类的其他方法
1、获取线程ID
public int getId()
2、获取当前运行的线程对象
public static Thread currentThread()
3、获取名字
public String getName()
4、设置为守护线程
public void setDaemon(true);
5、获取线程的工作状态
public int getState()
6、插队优先执行
public void join()
7、休眠
public static void sleep(long 毫秒数)
三、原子对象修改
1、有AtomicInteger和AtomicBoolean两种常用的原子类。
2、原子类的特点:每次修改变量的值是一次完成的,中间不受到其他线程打扰。
3、AtomicInteger的主要方法
// 获取值
public int get()
// 设置值
public void set(int k)
// 加一并且返回值
public int incrementAndGet()
// 减一并且返回值
public int decrementAndGet()
四、让属性值保持最新
1、用volatire关键字修饰属性
案例:
public volatie int k;
2、每次线程获取属性k都是最新的。
也就是另外一个线程修改属性k后,当前线程获取k的值是最新的。
五、加锁
(一)用synchronized关键字加锁
有两种方法:
1、锁住当前对象
只有获得对象的锁,才能执行被synchronized修饰的方法。
通俗解释:只要方法加了关键字synchronized,就是线程安全的。
public class F{
// 线程安全的方法
public synchronized void add(){
// 代码
}
}
2、锁住某个对象
只有拥有指定对象的锁,才能执行下列的代码块:
// 出现在要求安全执行的方法内部
synchronized(锁对象){
// 线程安全执行的代码块
}
案例:
锁对象一般是Object类型或者它的子类。
public class T{
// 自定义锁对象
private Object lock = new Object();
public void add(){
synchronized(lock){
// 安全执行的代码块
}
}
}
(二)用ReentrantLock来手动加锁
1、主要方法:
// 加锁
public void lock()
// 可中断加锁
public void lockInterruptibly() throws InterruptedException
// 解锁
public void unlock()
// 获得休眠和唤醒的条件对象
public Condition newCondtion()
注意:lock()方法执行时,如果获取不到锁,会一直等待,直到获取锁。
2、使用案例
public class Test{
// 创建锁对象
private ReentrantLock lock = new ReentrantLock();
public Test(){}
public void add(){
// 加锁
lock.lock();
// 需要安全执行的代码块
// 解锁
lock.unlock();
}
}