学习笔记——多线程及线程加锁

多线程

CPU的调度是抢占式的,相当于哪个程序抢到了就哪个程序先执行,也可能执行到一半别的程序又抢去执行,有一种同时进行的感觉。

线程基本流程

继承Theard方法

  1. 可以编写一个类去继承Thread类

  2. 在这个类里面去重写run方法

  3. 创建类对象调用start()方法。

例如:

public class Music extends Thread {
   @Override
   public void run() {
       System.out.println("听音乐。。。")
  }
}
public class StickTest01 {
   public static void main(String[] args) {
       new Music().start();
  }
}

通过Runnable实现线程的启动

  1. 写一个类去实现runnable的接口

  2. 重写run方法

  3. 创建Thread对象传入,传入实现类的对象

  4. 调用对象的start()方法;

    创建Thread对象传入,传入实现类的对象 如:

MyRunnable mr = new MyRunnable();

Thread th = new Thread(mr);

th.start();

线程不安全的本质就是:多个线程同时在修改一个资源,每个线程所看的数据不同。

解决方式:加锁


加锁

锁可以是任意对象,但是要保证多个线程用的是同一把锁,地址一样的锁。

锁:通常用当前类的字节码对象

同步代码块

synchronized (锁){
   // 需要同步的代码
}

中间的可以加当前的类.Class

 @Override
   public void run() {
       //卖票 50张
       while(num>0) {
           // 加锁
           synchronized (MyStick2.class){
               if (num>0) {
                   //27
                   System.out.println(Thread.currentThread().getName() + " : 在卖第" + num + "张票");
                   num--;
                   try {
                       sleep(200);
                  } catch (InterruptedException e) {
                       e.printStackTrace();
                  }
              }else{
                   return;
              }

          }

      }
  }

同步方法

方法的申明加关键字synchronized

private  synchronized static void extracted() {
       if (num > 0) {
           //27
           System.out.println(Thread.currentThread().getName() + " : 在卖第" + num + "张票");
           num--;
           try {
               sleep(200);
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
      }
  }

lock锁

ReentrantLock lock = new ReentrantLock();

创建一个lock,lock()加锁,unlock()解锁

个人感觉好理解

static ReentrantLock lock = new ReentrantLock();
 @Override
   public void run() {
       //卖票 50张
       while (num > 0) {
           lock.lock();// 加锁
           if (num > 0) {
               //27
               System.out.println(Thread.currentThread().getName() + " : 在卖第" + num + "张票");
               num--;
          }
           lock.unlock();//释放锁
           try {
               sleep(200);
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
      }
  }

对于加锁,核心是确保线程用的是同一把锁

 

 

posted @ 2021-12-08 20:03  Black空我  阅读(458)  评论(0编辑  收藏  举报