生产者和消费者
老版的(synchronized)生产者和消费者(等待/业务/通知)
public class Talksend {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for(int i=0;i<10;i++){
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for(int i=0;i<10;i++){
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
}
}
class Data{
private int number = 0;
//+1
public synchronized void increment() throws InterruptedException {
if(number!=0){
//等待
this.wait();
}
number++;
System.out.println(Thread.currentThread().getName()+"->"+number);
//通知其他线程,我+1完毕
this.notifyAll();
}
//-1
public synchronized void decrement() throws InterruptedException {
if(number==0){//1
//等待
this.wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"->"+number);
//通知其他线程,我-1完毕
this.notifyAll();
}
}
当然,这是这是两个线程的,一增一减(ok)
1.但是当你4个线程的情况,两增两减(出错),而且两个方法都有synchronized修饰了,why???
因为用 if 产生了虚假唤醒(当两个加线程同时进来,但是if只判断一次,符合,直接加了两下【synchronized只对你的成员数据有用,但是并不对你判断的时候起作用】),改为while就好了
JUC版的生产者和消费者
这个是没有synchronized的,有就会死锁
class Data{
private int number = 0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
//+1
public void increment() throws InterruptedException {
lock.lock();
try {
while(number!=0){
//等待
condition.await();
}
number++;
System.out.println(Thread.currentThread().getName()+"->"+number);
//通知其他线程,我+1完毕
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
//-1
public void decrement() throws InterruptedException {
lock.lock();
try {
while(number==0){//1
//等待
condition.await();
}
number--;
System.out.println(Thread.currentThread().getName()+"->"+number);
//通知其他线程,我-1完毕
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
condition的牛逼之处(多开几个condition监视器,按顺序打开)
public class Talksend {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for(int i=0;i<10;i++){
data.paint1();
}
},"A").start();
new Thread(()->{
for(int i=0;i<10;i++){
data.paint2();
}
},"B").start();
new Thread(()->{
for(int i=0;i<10;i++){
data.paint3();
}
},"C").start();
}
}
class Data{
private int number = 1;
Lock lock = new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
public void paint1(){
lock.lock();
try {
while (number != 1 ){
condition1.await();
}
number = 2;
System.out.println(Thread.currentThread().getName()+"正在执行");
condition2.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void paint2(){
lock.lock();
try {
while (number != 2 ){
condition2.await();
}
number = 3;
System.out.println(Thread.currentThread().getName()+"正在执行");
condition3.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
public void paint3(){
lock.lock();
try {
while (number != 3 ){
condition3.await();
}
number = 1;
System.out.println(Thread.currentThread().getName()+"正在执行");
condition1.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
【单例模式,排序算法,生产者和消费者,死锁】