java-线程安全问题,线程实现线程同步,线程状态,等待唤醒机制,生产者消费者模型

线程安全问题是不能产生的,我们可以让一个线程在访问共享数据的时候,无论是否失去了cpu的执行权,让其他的线程只能等待,等待当前线程执行完,其他线程在执行
保证始终是一个线程在执行

解决线程安全问题手段:线程同步

实现同步操作步骤

1.同步代码块

格式:
synchronized(锁对象){
可能会出现线程安全问题的代码(访问了共享数据的代码)
}
注意事项:
1.通过代码块中的锁对象,可以使用任意的对象
2.但是必须保证多个线程使用的锁对象是同一个
3.锁对象作用:
把同步代码块锁住,只让一个线程在同步代码块中执行
创建Runnable的实现类RunnableImple

//实现卖票案例:出现了线程安全问题,卖出了重复和不存在的票
public class RunnableImple implements Runnable {
    private int ticket = 100;

    //创建一个锁对象
    Object obj = new Object();

    @Override
    public void run() {
        while (true){
            //同步代码块
            synchronized (obj){
                if (ticket>0){
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket);
                    ticket--;


                }
            }
        }

    }
}

主程序

public class t1 {
    public static void main(String[] args){
        RunnableImple rnb = new RunnableImple();
        new Thread(rnb).start();
        new Thread(rnb).start();
        new Thread(rnb).start();
    }
}

同步技术原理:
同步中的线程,没有执行完毕不会释放锁,同步外的线程没有锁进不去同步
弊端
同步保证了只能有一个线程在同步中执行共享数据保证了数据
程序频繁的判断锁,释放锁,程序的效率会降低

2.同步方法

在这里插入图片描述
使用步骤:
1.把访问就共享数据的代码抽取处理,放到一个方法中
2.在方法上添加synchronized修饰符
创建Runntable实现类RunnableImple

//实现卖票案例:出现了线程安全问题,卖出了重复和不存在的票
public class RunnableImple implements Runnable {
    private int ticket = 100;

    @Override
    public void run() {
        while (true){
            payTicket();
        }
    }
    public synchronized void payTicket(){
        if (ticket>0){
            System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket);
            ticket--;
        }
    }
}

主程序

public class t1 {
    public static void main(String[] args){
        RunnableImple rnb = new RunnableImple();
        new Thread(rnb).start();
        new Thread(rnb).start();
        new Thread(rnb).start();
    }
}

静态同步方法

Runnable实现类RunnableImple

//实现卖票案例:出现了线程安全问题,卖出了重复和不存在的票
public class RunnableImple implements Runnable {
    private static int ticket = 100;

    @Override
    public void run() {
        while (true){
            payTicket();
        }
    }
    public static synchronized void payTicket(){
        if (ticket>0){
            System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket);
            ticket--;
        }
    }
}

主程序

public class t1 {
    public static void main(String[] args){
        RunnableImple rnb = new RunnableImple();
        new Thread(rnb).start();
        new Thread(rnb).start();
        new Thread(rnb).start();
    }

}

静态同步方法锁对象不能是this,this是创建对象之后产生的,静态方法要优先于对象
静态方法的锁对象是RunnableImple.class属性

3.Lock接口的锁机制

在这里插入图片描述
使用步骤:
在这里插入图片描述
创建Runnable实现类RunnableImple

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

//实现卖票案例:出现了线程安全问题,卖出了重复和不存在的票
public class RunnableImple implements Runnable {
    private static int ticket = 100;
    //1.创建ReentrantLock对象
    Lock l = new ReentrantLock();
    @Override
    public void run() {
        while (true){
            l.lock();
            try {
                Thread.sleep(10);
                if (ticket>0){
                    System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket);
                    ticket--;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                l.unlock();
            }


        }

    }
}

主程序

扫描二维码关注公众号,回复: 10554706 查看本文章
public class t1 {
    public static void main(String[] args){
        RunnableImple rnb = new RunnableImple();
        new Thread(rnb).start();
        new Thread(rnb).start();
        new Thread(rnb).start();
    }

}

线程状态

在这里插入图片描述

生产者消费者模型:等待唤醒

在这里插入图片描述

等待唤醒案例

在这里插入图片描述
notify()唤醒一个等待时间最久的线程
notifyall()唤醒所有等待线程

public class t1 {
    public static void main(String[] args){
        //创建锁对象
        Object obj = new Object();
        //顾客
        new Thread(){
            @Override
            public void run() {
              while (true){//一直等待买包子
                  //保证等待和唤醒只能有一个执行
                  synchronized (obj){
                      System.out.println("点餐");
                      try {
                          obj.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      //唤醒之后执行的代码
                      System.out.println("端上桌开吃");
                      System.out.println("-----------");
                  }
              }

            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (obj){
                        System.out.println("告知顾客取餐");
                        obj.notify();
                    }
                }
            }
        }.start();
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建一个资源类:包子类

public class rube {
    //皮
    String skin;
    String stuffing;
    boolean state = false;
}

创建生产者类:包子铺类

public class productionImpl extends Thread {
    private rube bz;

    public productionImpl(rube bz) {
        this.bz = bz;
    }
    @Override
    public void run() {
        int count = 0;
        while (true){
            synchronized (bz){
                if (bz.state==true){
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (count%2==0){
                    bz.skin="薄皮";
                    bz.stuffing="三鲜";
                }else{
                    bz.skin="冰皮";
                    bz.stuffing="牛肉";
                }
                count++;
                System.out.println("包子正在制作:"+bz.skin+bz.stuffing+"包子");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                bz.state=true;
                bz.notify();
                System.out.println("包子已经出锅上桌了 ");

            }
        }

    }
}

创建消费者类:顾客类

public class consumerImple extends Thread {
    private rube bz;

    public consumerImple(rube bz) {
        this.bz = bz;
    }

    @Override
    public void run() {
        while (true){
            synchronized (bz){
                if (bz.state==false){
                    try {
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("正在吃"+bz.skin+bz.stuffing+"的包子");
                bz.state=false;
                bz.notify();
                System.out.println("吃完了所有的包子,赶紧上菜!");
            }
            }

    }
}

主程序

public class t1 {
    public static void main(String[] args){
        rube bz = new rube();
        new productionImpl(bz).start();
        new consumerImple(bz).start();

    }

}
发布了33 篇原创文章 · 获赞 9 · 访问量 3864

猜你喜欢

转载自blog.csdn.net/weixin_45154559/article/details/105264644