synchronized同步

synchronized既可以对方法实现同步,也可以对代码块实现同步,示列如下:

// 未同步的方法
public void test() {}

// 同步的方法
pubilc synchronized void test() {}

//synchronized 也可以用在一个代码块上,看

public void test() {
     synchronized(obj) {
          System.out.println("===");
     }
}

使用synchronized代码块,可以只对需要同步的代码进行同步,这样可以提高效率。
synchronized也可以配合Object对象的wait()/notify()/nitifyAll()一起使用。如下列子所示:


package jalonTest;

/*
    Produce线程打印A,Consumer线程打印B。实现ABABAB交替打印。
    模拟生产者生产数据后,唤醒消费者消费数据。
*/

public class Test {

    static class Consumer implements Runnable {

         public  void run() {
                // TODO Auto-generated method stub
                int count = 10;
                while(count > 0) {
                     synchronized (Test. obj) {

                         try {
                               Test. obj.wait();

                         } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                               e.printStackTrace();
                         }

                         System. out.print( "B");
                         count --;

                         Test. obj.notify(); // 主动释放对象锁

                    }

               }
         }
    }

    static class Produce implements Runnable {

         public void run() {
                // TODO Auto-generated method stub
                //想想这里为什么要休眠一会呢?
                 try {
                    Thread.sleep(1000);
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }

                int count = 10;

                while(count > 0) {
                     synchronized (Test. obj) {

                          //System.out.print("count = " + count);

                         System. out.print( "A");
                         count --;
                         Test. obj.notify();

                         try {
                               Test. obj.wait();
                         } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                               e.printStackTrace();
                         }

                    }

               }

         }

    }

 public static final Object obj = new Object();

     public static void main(String[] args) {

            new Thread( new Produce()).start();
            new Thread( new Consumer()).start();

     }
}

Obj.wait(),与Obj.notify()必须要与synchronized(Obj)一起使用,也就是wait,与notify是针对已经获取了Obj锁进行操作,从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){…}语句块内。从功能上来说wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。相应的notify()就是对对象锁的唤醒操作。但有一点需要注意的是notify()调用后,并不是马上就释放对象锁的,而是在相应的synchronized(){}语句块执行结束,自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。这样就提供了在线程间同步、唤醒的操作。

想想在Produce线程中为什么要sleep一会?去掉试试,是否每次都能输出ABABABAB呢?
若不休眠存在一种可能,Produce在notify完毕时,Consumer还没进入wait状态,那就没得玩了。后续Produce会一直等待Consumer的notify而Consumer也在等待Produce的notify,这就是死锁!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值