编程语言
首页 > 编程语言> > JAVA多线程之线程安全

JAVA多线程之线程安全

作者:互联网

文章目录


前言

线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。


一、如何使线程安全?

给线程加把锁,JAVA中锁分两类,
显示锁:Lock
隐式锁:synchronized

二、隐式锁:synchronized

synchronized:Java中的关键字,是由JVM来维护的,是JVM层面的锁。

1.使用:同步代码块:让线程变得安全

代码如下(示例):

package com.demo.thread;

public class Demo5 {
    /**
     * @Description: 线程同步   synchronized
     * @Param: [args]
     * @return: void
     */
    public static void main(String[] args) {
        // 线程不安全
        // 解决方案1、:同步代码块
        /* 格式:synchronized(锁对象){
         *
         *       }
         * */
        MyRunnable myRunnable = new MyRunnable();
        new Thread(myRunnable).start();
        new Thread(myRunnable).start();
        new Thread(myRunnable).start();
    }

    static class MyRunnable implements Runnable {

        private int count = 10;
        private Object o = new Object(); //三条线程,一个对象。

        @Override
        public void run() {
            while (true) {
                synchronized (o) {   //线程同步
                    if (count > 0) {
                        System.out.println("正在准备卖票");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        count--;
                        System.out.println(Thread.currentThread().getName() + "出票成功:余票:" + count);
                    } else {
                        break;
                    }
                }
            }
        }
    }
}

2.使用:同步方法:让线程安全

代码如下(示例):

package com.demo.thread;

public class Demo6 {
    /**
     * @Description: 线程同步   synchronized
     * @Param: [args]
     * @return: void
     */
    public static void main(String[] args) {
        // 线程不安全
        // 解决方案2、:同步方法
        MyRunnable myRunnable = new MyRunnable();
        new Thread(myRunnable).start();
        new Thread(myRunnable).start();
        new Thread(myRunnable).start();
    }

    static class MyRunnable implements Runnable {

        private int count = 10;
        private Object o = new Object();

        @Override
        public void run() {
            while (true) {
                boolean flag = sale();
                if (!flag) {
                    break;
                }
            }
        }

        public synchronized boolean sale() {
            // 锁对象:在方法的内部操作的this是谁,那么这个锁就是谁。
            // 如果方法被静态修饰,那么锁就是  类名.class
            if (count > 0) {
                System.out.println("正在准备卖票");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count--;
                System.out.println(Thread.currentThread().getName() + "出票成功:余票:" + count);
                return true;
            }
            return false;
        }
    }
}

三、显示锁:Lock

Lock:是JDK5以后才出现的具体的类。使用lock是调用对应的API,是API层面的锁。

1.使用 Lock

// 显示锁 l
private Lock l = new ReentrantLock();

package com.demo.thread;

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

public class Demo7 {
    /**
     * 同步代码块 和 同步方法,称为 隐式锁
     *
     * @Description: 线程同步   Lock
     * @Param: [args]
     * @return: void
     */
    public static void main(String[] args) {
        // 线程不安全
        // 解决方案3、:显示锁 Lock 子类:ReentrantLock
        MyRunnable myRunnable = new MyRunnable();
        new Thread(myRunnable).start();
        new Thread(myRunnable).start();
        new Thread(myRunnable).start();
    }

    static class MyRunnable implements Runnable {

        private int count = 10;
        private Object o = new Object();
        // 显示锁 l  
        private Lock l = new ReentrantLock();

        @Override
        public void run() {
            while (true) {
                l.lock();  //上锁
                if (count > 0) {
                    System.out.println("正在准备卖票");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count--;
                    System.out.println(Thread.currentThread().getName() + "出票成功:余票:" + count);

                } else {
                    break;
                }
                l.unlock(); // 解锁
            }
        }

    }
}

标签:count,myRunnable,JAVA,Thread,线程,new,多线程,public
来源: https://blog.csdn.net/weixin_45663222/article/details/112150904