解决线程不安全的方式(Java)

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。解决线程不安全的方式(Java),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、同步代码块

package com.synchronized1;

// 买票示例
// 使用同步代码块解决线程安全问题
public class TicketRunnableImp implements Runnable {
    private int ticket = 100;
    Object o=new Object();
    @Override
    public void run() {
        while (true) {
            synchronized (o){
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + "-->正在售第"+ticket+"张票!");
                    ticket--;
                }
            }
        }
    }
}
实现原理:使用了一个锁对象.这个锁对象也叫同步锁,对象锁,对象监视器。先进入同步代码块的线程会先获取到锁对象,其他线程不能进入代码块,只有先进入同步代码块的线程
执行完毕同步代码块释放锁对象后,其他线程才有机会获取到锁对象进入同步代码块。也就是每次只有一个线程进入到同步代码块执行逻辑。

优点:实现了线程安全
缺点:程序不停的判断锁,获取锁,释放锁,效率会降低

二、同步方法

package com.synchronized2;

// 买票示例
// 使用同步方法解决线程安全问题
public class TicketRunnableImp implements Runnable {
    private int ticket = 100;
    Object o = new Object();

    @Override
    public void run() {
        while (true) {
            func();
        }
    }
    // 同步方法的锁对象是调用者对象(Runnable对象)
    public synchronized void func(){
        if (ticket > 0) {
            System.out.println(Thread.currentThread().getName() + "-->正在售第" + ticket + "张票!");
            ticket--;
        }
    }
}
实现原理:和同步代码块实现原理基本一致,同步方法中的锁对象是线程实现类的对象。

三、静态方法

package com.staticSyn;

// 买票示例
// 使用同步方法解决线程安全问题
public class TicketRunnableImp implements Runnable {
    private static int ticket = 100;
    Object o = new Object();

    @Override
    public void run() {
        while (true) {
            func();
        }
    }
    // 静态方法的锁对象是本类的class属性
    public synchronized static void func(){
        if (ticket > 0) {
            System.out.println(Thread.currentThread().getName() + "-->正在售第" + ticket + "张票!");
            ticket--;
        }
    }
}

四、Lock锁

方式一

package com.lock1;

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

// 买票示例
// 使用同步代码块解决线程安全问题
public class TicketRunnableImp implements Runnable {
    private int ticket = 100;
    Object o = new Object();
    Lock lock=new ReentrantLock();
    @Override
    public void run() {
        while (true) {
            lock.lock();
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + "-->正在售第" + ticket + "张票!");
                ticket--;
            }
            lock.unlock();
        }
    }
}

方式二

package com.lock2;

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

// 买票示例
// 使用同步代码块解决线程安全问题
public class TicketRunnableImp implements Runnable {
    private int ticket = 100;
    Object o = new Object();
    Lock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
            lock.lock();
            try {
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + "-->正在售第" + ticket + "张票!");
                    ticket--;
                }
            } catch (Exception e) {
                System.out.println(e);
            } finally {
                lock.unlock();
            }
        }
    }
}

五、上述几种方式的测试类

package com.lock2;

public class DemoTicket {
    public static void main(String[] args) {
        TicketRunnableImp t=new TicketRunnableImp();
        Thread t1=new Thread(t);
        Thread t2=new Thread(t);
        Thread t3=new Thread(t);
        t1.start();
        t2.start();
        t3.start();
    }
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/187718.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!