初步了解进程、线程

1、什么是进程

进程简单来说就是电脑的一个独立程序,进程之间是相互独立的。想要了解的可以参考任务管理器。

2、什么是线程

线程就是进程执行,且一个进程至少有一个线程。而我们说的多线程就涉及到串行和并行两个知识点。
串行就是单条线程执行多个任务。所以在执行A,B,C三个任务的时候只能当完成上一个任务之后才能继续执行下一个任务,在同一时间点上不能同事执行两个任务。
并行就是执行多个任务的时候可以同时执行,不需要A任务执行完之后才能执行其他任务。

多线程:比如说一些查杀病毒的软件,在同一时刻可以同时清理垃圾、查杀病毒、电脑加速等功能,没有明显的先后顺序。

3、什么是线程安全

当线程A进入方法拿到一个值(count=0),当值要改变还没有变的时候(count = count + 1),线程B进入该方法拿到的值则是线程A还没有改变的值,这样的程序无疑是不安全的。
所以当多个线程访问某个方法时,不管你通过怎样的调用方式、或者说这些线程如何交替地执行,我们在主程序中不需要去做任何的同步,这个类的结果行为都是我们设想的正确行为,那么我们就可以说这个类是线程安全的。

4、如何确保线程安全

  1. synchronized关键字就是来控制线程同步的,保证在多线程环境下,不被多个线程同时执行,确保数据的完整性。一般使用的方法是将其加在方法上(注意:synchronized锁的是括号里面的对象,而不是代码,其次,对于非静态的synchronized方法,锁的是对象本身也就是this)
    当synchronized锁住一个对象之后,别的线程如果想要获取锁对象,那么就必须等这个线程执行完释放锁对象之后才可以,否则一直处于等待状态。
    注意点:虽然加synchronized关键字,可以让我们的线程变得安全,但是我们在用的时候,要注意缩小synchronized的使用范围,随意使用synchronized时很影响程序的性能,别的对象想拿到锁,结果你没用锁还一直把锁占用,这样就浪费资源了。
public synchronized void threadMethod(int i)
  1. Lock是在我们需要的时候去手动获取锁和释放锁,从使用上说Lock明显没有synchronized使用起来方便快捷。
private Lock lock = new ReentrantLock(); // ReentrantLock是Lock的子类   
private void method(Thread thread){     
    lock.lock(); // 获取锁对象       
    try {           
    System.out.println("线程名:"+thread.getName() + "获得了锁");           
    // Thread.sleep(2000);       
    }catch(Exception e){        
       e.printStackTrace();    
          } finally {        
             System.out.println("线程名:"+thread.getName() + "释放了锁");        
             lock.unlock(); // 释放锁对象      
              }  
          }

进入方法的时候我们首先要获取到锁,然后执行我们的代码,Lock获取的对象需要我们自己去释放,所以一般释放锁我们都会放在finally里面,因为finally里面的代码都会被执行。
其实除了Lock还会有tryLock()方法来获取锁。Lock在获取锁定的时候如果没有拿到锁则会一直处于等待状态,直到拿到锁,但是tryLock()却是假设没有拿到锁则会直接返回一个Boolean的返回值,不会像Lock()那样去一直等待获取锁。

private void method(Thread thread) throws InterruptedException {       
      // lock.lock(); // 获取锁对象       
      // 如果5秒内获取不到锁对象,那就不再等待       
      if (lock.tryLock(5,TimeUnit.SECONDS)) {     
            try {          
                 System.out.println("线程名:"+thread.getName() + "获得了锁");    
                 }catch(Exception e){          
                      e.printStackTrace();      
                           } finally {         
                                 System.out.println("线程名:"+thread.getName() + "释放了锁");     
                                  lock.unlock(); // 释放锁对象      
                                      }   
                                 }
                         }

以上仅供自己参考

上一篇:Java中的重量级锁


下一篇:基于Redis实现分布式锁(二)