线程的同步

class ThreadText implements Runnable {
      private int num = 10;
      private Object obj = new Object();
          @Override
      public void run() {
              while (true) {
                  if (num > 0) {
                           try {
                           Thread.sleep(100);
                           } catch (InterruptedException e) {
                           e.printStackTrace();
                           }
                           System.out.println(num--);
                    }
          }
  }       

这段代码有线程安全问题,使用多线程时会发生数据错误。
原因:(也是我们以后判断一个程序是否有线程安全问题的依据)
a.线程任务中操作的是共享数据。
b.线程任务中操作共享数据的代码有多条(运行有多个)。
怎么解决?需要使用线程的同步机制。

class ThreadText implements Runnable {
      private int num = 10;
      private Object obj = new Object();
              @Override
      public void run() {
           synchronized (obj) {
           while (true) {
              if (num > 0) {
                       try {
                       Thread.sleep(100);
                       } catch (InterruptedException e) {
                       e.printStackTrace();
                       }
    }
    System.out.println(num--);
   }
  }
 }
}

(1)线程的同步机制。
好比一个人上洗手间时,他进入洗手间会上锁,出来的时候再把锁打开,然后其他人才能进去。

(2)在java中提供了同步机制,可以有效的防治资源冲突,同步机制使用synchronized关键字。
有一个前提:多个线程使用一把锁,这个才叫线程同步。

(2)在java中提供了同步机制,可以有效的防治资源冲突,同步机制使用synchronized关键字。
有一个前提:多个线程使用一把锁,这个才叫线程同步。

(3)同步的弊端:
a.降低了程序的效率。
b.当线程任务(run方法)中出现了多个同步,如果同步中嵌套了其他的同步,这个时候就会容易发生死锁。

例如

synchronized(obj 1){
                               synchronized(obj 2){    }
                        }
                     synchronized(obj 2){
                               synchronized(obj 1){    }
 }

4)同步机制解决的问题:
当多线程安全问题发生时,加入了同步后,就可以保证一个线程把所以的同步执行完,但是如果问题依旧,那么久要通过同步的
前提来判断同步是否正确。
注意:
如果当加上同步时,安全问题依旧,那么就要检查是否一个同步。

(5)同步块:
a.synchronized(obj){ } 这是一把锁
b.synchronized(new Object() ){ } 这样不是使用同一把锁 ,错误的写法。
通常将共享数据的操作放置在synchronized定义的区域内,这样当其他线程也获取到这个锁时,必须等待锁被释放时才能进入该区域。

(6)同步方法:就是在方法前面修饰synchronized关键字的方法。

例如

public synchronized void xd(){
             try {
           Thread.sleep(100);
                 } catch (InterruptedException e) {
           e.printStackTrace();
                 }
      System.out.println(num--);
 }
      @Override
 public void run() {
      while (true) {
         xd();
 }
}

注意:同步方法也是有锁的,它的锁是this。

(7) 静态同步方法:使用的锁是字节码文件对象。 字节码文件对象——> 类名.class

总结
当多线程任务只需要一个同步时完全可以使用同步方法,
当多线程任务需要多个同步时,必须要通过锁来进行区分,这时候必须要使用同步代码,所以同步代码较为常用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值