上一篇 <<<多线程基础
下一篇 >>>锁的深入化
线程安全: 当多个线程同时共享,同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。
做读操作是不会发生数据冲突问题。
tips:
a、局部变量不存在线程安全问题
b、只有全局变量才会存在线程安全问题
解决线程安全思路
synchronized方式
//写操作
synchronized (res) {
//如果已经写完,没被读的话,则等待读取
if(res.writeFlg){
try {
res.wait();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (count == 0) {
res.name = "老王";
res.sex = "男";
} else {
res.name = "小红";
res.sex = "女";
}
count = (count + 1) % 2;
//如果写完,则唤醒读
res.writeFlg = true;
res.notify();
}
//读操作
synchronized (res) {
//如果没有写,则等待先写
if(!res.writeFlg){
try {
res.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(res.name + "," + res.sex);
//读取完后,则设置为false,唤醒写程序
res.writeFlg = false;
res.notify();
}
Lock锁方式,不过wait和notify需要改为await和signal
public Lock lock = new ReentrantLock();
public Condition condition = lock.newCondition();
// 写操作
try {
res.lock.lock();
try {
if(res.writeFlg) {
res.condition.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (count == 0) {
res.name = "老王";
res.sex = "男";
} else {
res.name = "小红";
res.sex = "女";
}
count = (count + 1) % 2;
res.writeFlg = true;
res.condition.signal();
} finally {
res.lock.unlock();
}
// 读操作
try {
res.lock.lock();
try {
if(!res.writeFlg) {
res.condition.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(res.name + "," + res.sex);
res.writeFlg = false;
res.condition.signal();
} finally {
res.lock.unlock();
}
wait和notfiy的区别
注意:一定要在线程同步中使用,并且是同一个锁的资源
wait和sleep的区别
synchronized和lock锁的区别
LockSupport的pack/unpack与Synchronized的wait/notify区别?
相关文章链接:
<<<多线程基础
<<<锁的深入化
<<<锁的优化
<<<Java内存模型(JMM)
<<<Volatile解决JMM的可见性问题
<<<Volatile的伪共享和重排序
<<<CAS无锁模式及ABA问题
<<<Synchronized锁
<<<Lock锁
<<<AQS同步器
<<<Condition
<<<CountDownLatch同步计数器
<<<Semaphore信号量
<<<CyclicBarrier屏障
<<<线程池
<<<并发队列
<<<Callable与Future模式
<<<Fork/Join框架
<<<Threadlocal
<<<Disruptor框架
<<<如何优化多线程总结