文章目录
基本概念
共享变量
共享变量必须要保证线程安全,对于共享变量复合操作,保证复合操作的线程安全性。
线程通信协作的最常见方式
- syncrhoized加锁的线程的Object类的wait()/notify()/notifyAll()
- ReentrantLock类加锁的线程的Condition类的await()/signal()/signalAll()
线程同步
一个线程对共享数据的操作应该具有原子性,在对共享数据进行操作没有完成操作之前,其他线程不允许打断该线程的操作,不能使共享数据的完整性得到破坏。
实现线程同步的方法:
同步代码方法:sychronized 关键字修饰的方法
同步代码块:sychronized 关键字修饰的代码块
使用特殊变量域volatile实现线程同步:volatile关键字为域变量的访问提供了一种免锁机制
使用重入锁实现线程同步:reentrantlock类是可冲入、互斥、实现了lock接口的锁他与sychronized方法具有相同的基本行为和语义
线程互斥
对于共享的资源,只允许一个线程访问,其他线程不能进行访问,如果多个线程要使用使用该资源的线程必须等待,直到占用资源者释放该资源。
多线程安全
使用synchronized关键字
同步方法块:
public class SyncronizedDemo implements Runnable {
private int count = 5;
@Override
public synchronized void run() {
count--;
System.out.println(Thread.currentThread().getName()+" count = "+count );
}
public static void main(String[] args) {
//创建
SyncronizedDemo thread = new SyncronizedDemo();
for(int i = 0 ; i < 5 ;i++){
new Thread(thread).start();
}
}
}
同步代码块
/**
* synchronized实现线程输出
*/
public class SyncronizedDemo implements Runnable {
private int count = 5;
private final Object o = new Object();
/*@Override
public synchronized void run() {
count--;
System.out.println(Thread.currentThread().getName()+" count = "+count );
}*/
@Override
public void run() {
synchronized (o) {
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
}
public static void main(String[] args) {
//创建
SyncronizedDemo thread = new SyncronizedDemo();
for(int i = 0 ; i < 5 ;i++){
new Thread(thread).start();
}
}
}
输出结果:
Thread-0 count = 4
Thread-4 count = 3
Thread-3 count = 2
Thread-2 count = 1
Thread-1 count = 0
使用并发包下的类实现同步
AtomicInteger,AtomicBoolean,AtomicLong等
/**
* synchronized实现线程输出
*/
public class SyncronizedDemo implements Runnable {
private AtomicInteger count = new AtomicInteger(5);
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " count = " + count.decrementAndGet());
}
public static void main(String[] args) {
//创建
SyncronizedDemo thread = new SyncronizedDemo();
for(int i = 0 ; i < 5 ;i++){
new Thread(thread).start();
}
}
}
使用Lock来实现
public class Lock implements Runnable{
private int count = 5;
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
lock. lock();
try {
System.out.println(Thread.currentThread().getName()+"获得锁 :Count = "+count--);
} catch (Exception e) {
e.printStackTrace();
} finally {
System. out. println(Thread.currentThread().getName()+"释放锁");
lock. unlock();
}
}
public static void main(String[] args) {
Lock thread = new Lock();
for(int i = 0 ; i < 5 ;i++){
new Thread(thread).start();
}
}
}
打印输出:
Thread-0获得锁 :Count = 5
Thread-0释放锁
Thread-1获得锁 :Count = 4
Thread-1释放锁
Thread-2获得锁 :Count = 3
Thread-2释放锁
Thread-3获得锁 :Count = 2
Thread-3释放锁
Thread-4获得锁 :Count = 1
Thread-4释放锁