synchronized关键字

synchronized是Java并发编程中的同步机制关键字,它能保证同一个时刻只有一条线程能够执行被关键字修饰的代码,其他线程就会在队列中进行等待,等待这条线程执行完毕后,下一条线程才能对执行这段代码。

synchronized的应用:

 1.修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁

 2.修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁

 3.修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁

假如我们有一个简单的卖票系统如下:

public class Thread
{
    public static void main(String [] args)
    {
       Tickets tickets=new Tickets(100);

       Operate operate=new Operate(tickets);
       new Thread(()->{
           while(tickets.getNum()>0) operate.sale();
       },"窗口1").start();
        new Thread(()->{
            while(tickets.getNum()>0) operate.sale();
        },"窗口2").start();
        new Thread(()->{
            while(tickets.getNum()>0) operate.sale();
        },"窗口3").start();
        new Thread(()->{
            while(tickets.getNum()>0) operate.sale();
        },"窗口4").start();
    }
}
public class Tickets {
    private int num;
    public Tickets(){};
    public Tickets(int num){
        this.num=num;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }
}
public class Operate {
    private Tickets tickets;
    public Operate(Tickets tickets){
        this.tickets=tickets;
    }
    public void sale(){
            if(tickets.getNum()>0){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                if(tickets.getNum()>0){
                    int num=tickets.getNum();
                    System.out.println(Thread.currentThread().getName()+"正在
卖票:"+tickets.getNum()+"售票剩余"+num);
                    --num;
                    tickets.setNum(num);
                }
        }
    }
}

 synchronized作用于实列方法

当synchronized关键字修饰实例方法时,它会获取当前实例对象的锁,并对整个方法体进行同步控制。只有获取到锁的线程才能执行该方法,其他线程需要等待锁释放。

在上述卖票系统的例子中,如果将synchronized关键字应用于实例方法sale(),则代码如下:

public synchronized void sale() {
    // 。。。。。。
}

在这种情况下,每个窗口线程在调用sale()方法时,都会尝试获取当前Tickets实例对象的锁。只有一个线程能够获取锁,执行售票逻辑,其他线程需要等待锁释放。这样可以确保每次只有一个线程执行售票操作,避免并发问题。

synchronized作用于静态方法

当synchronized关键字修饰静态方法时,它会获取该方法所属类的Class对象的锁,并对整个静态方法进行同步控制。只有获取到锁的线程才能执行该静态方法,其他线程需要等待锁释放。

在上述卖票系统的例子中,如果将synchronized关键字应用于静态方法sale(),则代码如下:

public static synchronized void sale() {
 // 。。。。。。 
}

在这种情况下,无论创建了多少个Tickets实例对象,所有窗口线程在调用sale()方法时,都会尝试获取Tickets.class对象的锁。只有一个线程能够获取锁,执行售票逻辑,其他线程需要等待锁释放。这样可以确保每次只有一个线程执行售票操作,避免并发问题。

synchronized作用于代码块

synchronized关键字还可以应用于代码块级别,即修饰一段代码块。在这种情况下,它会获取指定对象的锁,并对代码块进行同步控制。只有获取到锁的线程才能执行该代码块,其他线程需要等待锁释放。

在上述卖票系统的例子中,如果将synchronized关键字应用于代码块,代码如下:

public void sellTicket() {
    // ......

    synchronized (this) {
        //......
    }

}

在这种情况下,通过synchronized关键字修饰的代码块,使用this作为锁对象。当一个线程进入同步代码块时,它会获取当前实例对象的锁。其他线程如果也想执行该代码块,则需要等待锁释放。

synchronized的包含三个特性:

1.原子性:使用synchronized实现了同步,同步实现了原子性,保证了被同步的代码块在同一时间只有一个线程在执行。

2.可见性:当一个线程修改了共享变量的值时,其他线程能够立即得知这个修改。

3.有序性:禁止代码重排序

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值