Java中synchronized关键字的用法

1.同步问题

在多线程下每一个线程对象轮番抢占资源,这个造成了很大的问题。比如当多个线程买票出现了负数,这种问题被称为不同步操作,不同步的好处是多个线程并发执行,这样处理速度快,synchronized是Java中的关键字,它主要解决的是线程同步问题。
同步处理:所有线程不是同时获取资源,而是按顺序一个一个来。那这就需要一把锁,锁住对应的资源,但是不同锁锁的是不同的资源。内建锁:(synchronized):JDK1.0作为关键提供的手段。

2.同步代码块:

使用synchronized作用于方法里,但是进入到方法中的线程依然有多个,是在方法里进行拦截,同一时刻只能有一个线程进入代码块,方法内仍然是多线程。
总结:

synchronized(this/  当前类.class  / 任意Object的子类对象)  {同步代码段}

总结:

  • synchronized(this){}:锁类的实例对象(当前对象)
  • synchronized(类名称.class){}:锁类对象(class对象)
  • synchronized(任意类对象){}:任意Object的子类对象

3.同步方法

方法上添加synchronized关键字,表示此方法只有一个线程能进入, 使用synchronized作用于方法头,同一时刻只有一个线程进入此方法

    public synchroized void sale()
    public static synchroized  void sale()

总结:

  • synchronized+普通方法:锁当前对象
  • synchronized+静态方法:锁当前类的对象(class对象)

所有代码示例:

package JavaSe.mult;

//class Buy implements Runnable{
//    private int ticket=100;
//    @Override
//    public void run() {
//        for(int i=0;i<100;i++){
//            synchronized (this){//表示为程序逻辑上锁,在一个时刻只可以有一个线程进入代码块
//                if(this.ticket>0){
//                    try {
//                        Thread.sleep(20);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace( );
//                    }
//                    System.out.println(Thread.currentThread().getName()+"还有"+this.ticket--+"票" );
//                }
//            }
//        }
//    }
//}


//class Buy implements Runnable{
//    private int ticket=100;
//    @Override
//    public void run() {
//        for(int i=0;i<100;i++){
//           this.sale();
//        }
//    }
//    public synchronized void sale(){//任意时刻只有一个线程进入此方法,隐式锁对象
//        if(this.ticket>0){
//            try {
//                Thread.sleep(20);
//            } catch (InterruptedException e) {
//                e.printStackTrace( );
//            }
//            System.out.println( Thread.currentThread().getName()+"还有"+this.ticket--+"票");
//        }
//    }
//}

//
//class Buy extends Thread{
//    @Override
//    public void run() {
//        Sync sync=new Sync();
//        sync.test();//锁的是多对象,任意时刻只有一个线程(同一个对象)能进入此方法
//    }
//}
//class Sync{
//    public synchronized void test(){
//        System.out.println("test方法开始,当前线程为"+Thread.currentThread().getName() );
//        try {
//            Thread.sleep(30);
//        } catch (InterruptedException e) {
//            e.printStackTrace( );
//        }
//        System.out.println("test方法结束,当前线程为"+Thread.currentThread().getName() );
//    }
//}



class Buy implements Runnable{
    //Sync sync=new Sync();也是一把锁
    @Override
    public void run() {
        Sync sync=new Sync();//三把锁
        sync.test();//锁的是多对象,任意时刻只有一个线程(同一个对象)能进入此方法
    }
}
class Sync{
    //public static synchronized void test(){//与对象无关了,synchronized修饰的是静态方法,
    //或者是synchronized(类名称,class) 则锁的是当前类的反射对象(class对象)(全局唯一)
    public void test(){
        synchronized (Sync.class){
        System.out.println("test方法开始,当前线程为"+Thread.currentThread().getName() );
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace( );
        }
        System.out.println("test方法结束,当前线程为"+Thread.currentThread().getName() );
       }
    }
}
public class TestSynchronized {
    public static void main(String[] args) {
//        Buy buy=new Buy();
//        Thread thread1=new Thread(buy,"A");
//        Thread thread2=new Thread(buy,"B");
//        Thread thread3=new Thread(buy,"c");
//
//        thread1.start();
//        thread2.start();
//        thread3.start();
        Buy buy=new Buy();
        for(int i=0;i<3;i++){
            Thread thread=new Thread(buy);
            thread.start();
        }
    }
}

同步虽然可以保证数据的完整性(线程安全操作),但是其执行的速度会很慢

在这里插入图片描述

4.全局锁:

实现全局锁的方式:
a.synchronized(类.class对象)
b.使用static synchronized方法
全局锁,与实例对象无关,锁的类(class)对象!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值