1. Java线程加锁的三种方式

对象锁:顾名思义给对象上锁

当A线程访问一个object的时候,首先会获取该对象的对象锁,然后访问锁定的代码,而B线程访问一个对象object代码区时,因为线程A之前获取到对象object的对象锁,因此线程B访问同步代码区的时候会被阻塞,直到线程A执行完同步代码块,然后释放对象锁,B线程获取对象object的对象锁,才能进行访问同步代码块

用法:synchronized (this){
//—-同步代码块———
}
this表示当前访问同步代码区的对象
特别注意:只要同步代码区的是同一个对象时才能实现互斥访问的效果

2. 对象锁(同步块)

对象锁(同步块)锁某一个对象

  1. package com.demo;
  2. public class SyncBlock {
  3. public static int count;
  4. public static Object lock = new Object();
  5. public static void main(String[] args) throws InterruptedException {
  6. Thread t1=new Thread(new MyRunnable(),"线程1");
  7. Thread t2=new Thread(new MyRunnable(),"线程2");
  8. t1.start();
  9. t2.start();
  10. t1.join();
  11. t2.join();
  12. System.out.println("count="+count);
  13. }
  14. static class MyRunnable implements Runnable{
  15. @Override
  16. public void run() {
  17. for (int i = 0; i < 10000; i++) {
  18. synchronized (lock) {
  19. count++;
  20. }
  21. }
  22. }
  23. }
  24. }

3. 类锁 锁当前类

锁当前类(方法上有static关键字修饰)

类锁:顾名思义给类上锁–>具体就是给类的字节码上锁

当线程A访问类锁锁定的同步代码块时,线程B访问同步代码块,因为A之前已经获取类锁,因此线程B只能A执行完同步代码块后才能获取类锁进行访问

  1. package com.demo;
  2. public class SyncClass {
  3. private static int count;
  4. public static void main(String[] args) throws InterruptedException {
  5. Thread t1 = new Thread(new MyRunnable());
  6. Thread t2 = new Thread(new MyRunnable());
  7. t1.start();
  8. t2.start();
  9. t1.join();
  10. t2.join();
  11. System.out.println(count);
  12. }
  13. static class MyRunnable implements Runnable{
  14. public static synchronized void increase() {
  15. count++;
  16. }
  17. @Override
  18. public void run() {
  19. for(int i=0;i<10000;i++) {
  20. increase();
  21. }
  22. }
  23. }
  24. }

4. 实例锁 锁的是当前实例

(方法上没有static修饰,表示只能锁当前实例)