解决多线程中线程安全的方式一

复制代码
/**
* 方式一:同步代码块
*   synchronized(同步监视器){
*       //需要被同步的代码,被同步的代码一定要慎重选择,多了或少了都会有问题
*
*   }
*   说明:1.操作共享数据的代码,即为需要被同步的代码,如对总票数的减减、判断是否大于0等操作
*       2.共享数据:多个线程共同操作的变量,如总票数
*       3.同步监视器:俗称“锁”,任何一个类的对象都可以充当锁  如Object obj = new Object();obj就可以充当锁
*               要求:多个线程必须要共用同一把锁,如果加上synchronized还是出现错误、重复等问题数据,首先要判断是否用的是同一个锁
          对于实现Runnable开启多线程的方法来说,同步锁可以考虑用this来代替,因为这种方式开启的线程只会实例化一次,所以this是唯一的
          对于继承Thread开启多线程的方法来说,同步锁可以考虑用当前类本身来代替(类.class),慎用this来代替,因为这种方式开启的线程有可能会实例化多次,this不是唯一的 
     4.开启线程的方式不同,确定共享数据和同步监视器的方式也不一样
        1.继承:需要将共享数据和同步监视器用static修饰,因为有可能会实例化多次
            2.实现:不需要用static修饰,只需声明为全局变量即可,因为只实例化一次
*
*/
复制代码
public class ThreadCodeDemo {

    public static void main(String[] args) {
        ThreadImp threadImp = new ThreadImp();

        Thread window1 = new Thread(threadImp);
        Thread window2 = new Thread(threadImp);
        Thread window3 = new Thread(threadImp);

        window1.setName("Runnable窗口1");
        window2.setName("Runnable窗口2");
        window3.setName("Runnable窗口3");

        window1.start();
        window2.start();
        window3.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("========================");
        ThreadExtends threadExtends1 = new ThreadExtends();
        ThreadExtends threadExtends2 = new ThreadExtends();
        ThreadExtends threadExtends3 = new ThreadExtends();

        threadExtends1.setName("Thread窗口1");
        threadExtends2.setName("Thread窗口2");
        threadExtends3.setName("Thread窗口3");

        threadExtends1.start();
        threadExtends2.start();
        threadExtends3.start();

    }

}

/*实现Runnable方式*/
class ThreadImp implements Runnable {
    //总票数
    private int ticket = 100;
//    Object object = new Object();
    @Override
    public void run(){
        while(true) {
            synchronized (this) {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket);
                    ticket--;
                } else {
                    break;
                }
            }
        }
    }
}

/*继承Thread方式*/
class ThreadExtends extends Thread{
    private static int ticket = 100;
//    static Object object = new Object();
    @Override
    public void run() {
        while(true){
            synchronized(ThreadExtends.class){
                if(ticket > 0){
                    System.out.println(Thread.currentThread().getName() + "卖票,票号为:" + ticket);
                    ticket--;
                }else{
                    break;
                }
            }
        }
    }
}
复制代码

 

复制代码

 

posted @   那、就这样吧  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示