java多线程实现数据共享

来源:互联网 发布:mysql大数据统计报表 编辑:程序博客网 时间:2024/06/06 17:42

练习题:卖100个苹果,实现数据共享。

新建一个线程有两种方式:1.继承Thread类;2.是实现Runnable的方式:

那我们就先使用第一种方式来实现:

使用Thread实现数据的共享

第一步:

写一个了ShareThread继承Thread,并在ShareThread定义一个静态的Apple_Counts变量(注意:Apple_Counts因为是静态的,所以是共享数据)

    /**     * 存在数据共享     * @author liujun     *     */    class ShareThread extends Thread{        private static int Apple_Counts=100;//共享数据-苹果个数        @Override        public void run() {            while(Apple_Counts>0){                    if (Apple_Counts>0) {                        try {                            Thread.sleep(10);                            System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);                        } catch (InterruptedException e) {                            // TODO Auto-generated catch block                            e.printStackTrace();                        }                    }            }        }    }

在main方法开始三个线程:

    ShareThread mShareThread1=new ShareThread();    ShareThread mShareThread2=new ShareThread();    ShareThread mShareThread3=new ShareThread();    mShareThread1.start();    mShareThread2.start();    mShareThread3.start();

执行的结果:

Thread-0卖了一个苹果,还剩99Thread-1卖了一个苹果,还剩98Thread-2卖了一个苹果,还剩99Thread-0卖了一个苹果,还剩97//这里数据出现有错,因为上面的线程里没有使用同步锁Thread-1卖了一个苹果,还剩97................................................Thread-0卖了一个苹果,还剩2Thread-2卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0Thread-0卖了一个苹果,还剩-1 //这里数据出现有错,因为上面的线程里没有使用同步锁Thread-2卖了一个苹果,还剩-2

第二步:

给ShareThread中添加同步代码块:

    /**     * 存在数据共享     * @author liujun     *     */    class ShareThread extends Thread{        private static int Apple_Counts=100;//共享数据-苹果个数        @Override        public void run() {            while(Apple_Counts>0){                //注意这里添加了同步代码块,同步锁对象是this                synchronized (this) {                    if (Apple_Counts>0) {                        try {                            Thread.sleep(10);                            System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);                        } catch (InterruptedException e) {                            // TODO Auto-generated catch block                            e.printStackTrace();                        }                    }                }            }        }    }

再次执行main方法打印的结果:

Thread-2卖了一个苹果,还剩98Thread-1卖了一个苹果,还剩99Thread-0卖了一个苹果,还剩97Thread-1卖了一个苹果,还剩96Thread-0卖了一个苹果,还剩95................................................Thread-0卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0Thread-2卖了一个苹果,还剩0 //这里数据出现有错,都使用同步锁了?为什么????????Thread-0卖了一个苹果,还剩-1 

第三步:

分析代码:

多线程在使用synchronized的时候,多个线程使用的锁对象必须是同一个。

    ShareThread mShareThread1=new ShareThread();    ShareThread mShareThread2=new ShareThread();    ShareThread mShareThread3=new ShareThread();

上面这三行代码new了三个对象,那么上面使用的同步锁是this;那上面的多线程在使用synchronized的时候,多个线程使用的锁对象(this)不是同一个,它们是分别为mShareThread1,mShareThread2,mShareThread3。所以上面虽然使用了synchronized还是会出现数据有错。

第四步:

修改代码:

保证使多线程在使用synchronized的时候,多个线程使用的锁对象是同一个就行,下面使用了的同步锁对象是:ShareThread.class。

    /**     * 存在数据共享     * @author liujun     *     */    class ShareThread extends Thread{        private static int Apple_Counts=100;//共享数据-苹果个数        @Override        public void run() {            while(Apple_Counts>0){                //注意这里添加了同步代码块,同步锁对象是ShareThread.class                synchronized (ShareThread.class) {                    if (Apple_Counts>0) {                        try {                            Thread.sleep(10);                            System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);                        } catch (InterruptedException e) {                            // TODO Auto-generated catch block                            e.printStackTrace();                        }                    }                }            }        }    }

再次执行main方法打印的结果正常:

Thread-2卖了一个苹果,还剩98Thread-1卖了一个苹果,还剩99Thread-0卖了一个苹果,还剩97Thread-1卖了一个苹果,还剩96Thread-0卖了一个苹果,还剩95................................................Thread-0卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0

总结:

1.上面通过继承Thread类的方式已经实现数据共享,但是一般我们不定义静态的变量作为数据共享,因为静态的生命周期比较长。

2.建议实现数据共享时使用实现runnable来实现。

使用Runnable实现数据的共享

第一步:

写一个了ShareRunable实现Runnable,并在ShareRunable定义一个Apple_Counts变量(注意:Apple_Counts是共享数据)

    /**     * 存在数据共享     * @author liujun     *     */    class ShareRunable implements Runnable{        private int Apple_Counts=100;//Apple_Counts就是共享数据        @Override        public void run() {            while(Apple_Counts>0){                if(Apple_Counts>0){                    try {                        Thread.sleep(10);                        System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                }            }        }    }

在main方法开始三个线程:

    ShareRunable mMyRunables=new ShareRunable();    new Thread(mMyRunables).start();    new Thread(mMyRunables).start();    new Thread(mMyRunables).start();

执行的结果:

Thread-0卖了一个苹果,还剩99Thread-1卖了一个苹果,还剩98Thread-2卖了一个苹果,还剩99................................................Thread-0卖了一个苹果,还剩2Thread-2卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0Thread-0卖了一个苹果,还剩-1 //这里数据出现有错,因为上面的线程里没有使用同步锁Thread-2卖了一个苹果,还剩-2

第二步:

给ShareRunable中添加同步代码块:

    /**     * 存在数据共享     * @author liujun     *     */    class ShareRunable implements Runnable{        private int Apple_Counts=100;//Apple_Counts就是共享数据        @Override        public void run() {            while(Apple_Counts>0){            //注意这里添加了同步代码块,同步锁对象是this或者是ShareThread.class                synchronized (this) {                if(Apple_Counts>0){                    try {                        Thread.sleep(10);                        System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);                    } catch (InterruptedException e) {                        // TODO Auto-generated catch block                        e.printStackTrace();                    }                }               }                }        }    }

再次执行main方法打印的结果正常:

Thread-2卖了一个苹果,还剩99Thread-1卖了一个苹果,还剩98Thread-0卖了一个苹果,还剩97Thread-1卖了一个苹果,还剩96Thread-0卖了一个苹果,还剩95................................................Thread-0卖了一个苹果,还剩1Thread-1卖了一个苹果,还剩0

总结:

1.上面通过实现Runable类的方式已经实现数据共享

2.建议实现数据共享时使用实现runnable来实现。

0 0
原创粉丝点击