线程安全

三世轮回 提交于 2019-11-27 18:02:37

单线程相当于一个人做一件事,而多线程程序中,当需要多个线程共享同一个数据时,一个线程对共享的数据进行修改时,在他没有完成相关操作之前不允许其他线程进行相关操作,否则会出现线程安全问题。

package pers.zhb.runnable;

public class MyThread implements Runnable {
    private int tickets = 10;

    public void run() {
        while (true) {
            if (tickets > 0)
                System.out.println(Thread.currentThread().getName()
                        + "售票窗口,售卖了" + tickets-- + "号票");
            else
                System.exit(0);
        }

    }

}
package pers.zhb.runnable;

public class RunnableDemo {
    public static void main(String[] args) {
        MyThread mt=new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        Thread thread4 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
}

可以看出,10号票在被1号窗口卖出后,又被2号窗口卖了一次,显然这是不符合常理的。产生的原因是这样的:2号线程开始执行,tickets为10,进行了 if (tickets > 0);语句的执行,可以继续往下执行了,但是他没有抢夺到CPU资源,接着是1号线程读取数据10,进行判断可以执行,1号线程执行完后,2号线程依旧没有抢夺到CPU资源,只能继续等待。接着是3号线程、0号线程进行相关操作。当2号线程抢夺到CPU资源时,他的数据还是10,就造成了有重复票的情况。

添加同步语句:

package pers.zhb.runnable;

public class MyThread implements Runnable {
    private int tickets = 10;
    Object lock = new Object();

    public void run() {

        synchronized (lock) {
            while (true) {
                if (tickets > 0)
                    System.out.println(Thread.currentThread().getName()
                            + "售票窗口,售卖了" + tickets-- + "号票");
                else
                    System.exit(0);
            }
        }

    }

}
package pers.zhb.runnable;

public class RunnableDemo {
    public static void main(String[] args) {
        MyThread mt=new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        Thread thread4 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
}

创建同步方法:

package pers.zhb.runnable;

public class MyThread implements Runnable {
    private int tickets = 10;
    Object lock = new Object();

    public void run() {
        while (true)
            lock();

    }

    public synchronized void lock() {
        while (true) {
            if (tickets > 0)
                System.out.println(Thread.currentThread().getName()
                        + "售票窗口,售卖了" + tickets-- + "号票");
            else
                System.exit(0);
        }
    }
}
package pers.zhb.runnable;

public class RunnableDemo {
    public static void main(String[] args) {
        MyThread mt=new MyThread();
        Thread thread1 = new Thread(mt);
        Thread thread2 = new Thread(mt);
        Thread thread3 = new Thread(mt);
        Thread thread4 = new Thread(mt);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();

    }
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!