线程安全的方式

线程安全的方式

线程不安全是因为多个线程同时执行同一段内容,如果内容更改未完成,则出现不安全问题

实现线程安全就是将本可以多个线程同步执行的,改为即使建立多个线程,也要排队使用,线程安全就会带来效率变低的问题。

方案一:同步代码块

格式:synchronized(锁对象){}

将需要安全的线程内容放入代码块中,其中的锁对象可以是任意一个Object对象,同一个锁的对象应该用同一把锁,所以锁的建立应该在run()方法外。

在同步代码块内的内容同一时间只能执行一个。其余的线程也要按照顺序来进行执行。

方案二:同步方法

与同步代码块类似都是使用synchronized关键字,不过同步方法是用关键字修饰方法。

格式:public synchronized void lmzaixxq(){}

该方式是通过关键字来修饰方法,被修饰的方法在执行时只能排队执行。

同时这里需要注意一个大家平时忽略的问题,首先synchronized锁的是括号里的对象,而不是代码,其次,对于非静态的synchronized方法,锁的是对象本身也就是this。

当synchronized锁住一个对象之后,别的线程如果想要获取锁对象,那么就必须等这个线程执行完释放锁对象之后才可以,否则一直处于等待状态。

方案三:显示锁

线程在执行时,是可以任意的执行任务的,但是我们可以采用一种方式让其被占用后不能被其他线程再次调用,该方法就是将其上锁。

在任务中创建锁的对象。

public class Demo {
    public static void main(String[] args) {
        Runnable run = new MyRunnable();
        new Thread(run).start();
        new Thread(run).start();
        new Thread(run).start();

    }

}

class MyRunnable implements Runnable{
	//在任务中创建锁对象
    private Lock l = new ReentrantLock();
    private int count = 10;
    @Override
    public void run() {
        while (true) {
        //调用锁的方法
            l.lock();
            if (count>0) {
                System.out.println("throw tick");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count--;
                System.out.println("residual tick number:" + count);
            }else break;
            //使用完毕该内容,解开锁,允许其他线程进行调用,根据抢占法,所有线程开始抢占执行线程。
            l.unlock();
        }
    }
}

锁的建立其实就是线程执行中的一个先后判断的顺序,一旦建立了锁,就是排队执行线程,根据抢占式的方法来进行抢占。

将三种方法再进行一下分类,其实是同步代码块和同步方法属于隐式锁,显示锁是单独的一个。

所以可以看出为实现线程安全,其实都是锁的建立,只是隐式锁是通过关键字的修饰来实现的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值