赞
踩
目录
线程1上锁之后,线程2无法获取锁不能够执行临时区,线程2阻塞等待线程1完成释放锁之后才能够使用。可以把synchronize类比成一个房间,每次有锁的人才能够进入房间做事情,就算cpu时间片用完,只要没有这个锁那么其他线程是无法进入房间的。当用完之后就会释放锁,并且唤醒那些阻塞的线程
解决
@Slf4j public class Test { static int counter = 0 ; // 定义锁对象 static Object lock = new Object(); public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() ->{ for (int i = 0; i < 5000; i++) { synchronized (lock){ // 上锁 counter ++ ; } } }); Thread t2= new Thread(() ->{ for (int i = 0; i < 5000; i++) { synchronized (lock){ counter -- ; } } }); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(counter); } }
synchonized实际上是使用对象锁保证了临界区内代码的原子性,临界区是不可分割的,不会被线程切换打断
@Slf4j public class Test { public static void main(String[] args) throws InterruptedException { Room room = new Room(); Thread t1 = new Thread(() ->{ for (int i = 0; i < 5000; i++) { room.increment(); } }); Thread t2= new Thread(() ->{ for (int i = 0; i < 5000; i++) { room.decrement(); } }); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(room.getCounter()); } } class Room{ int count = 0 ; public void increment(){ synchronized (this){ count ++ ; } } public void decrement(){ synchronized (this){ count --; } } public int getCounter(){ synchronized (this){ return count; } } }
class c1{ public synchronized void test(){ } } class c1{ public void test(){ synchronized (this){ } } } 二者等价,锁住的是this对象
加载静态方法上相当于锁住类对象
情况1 : 1 2或者2 1
@Slf4j public class Test { public static void main(String[] args) throws InterruptedException { Number n1 = new Number(); new Thread(() -> { log.debug("begin"); n1.a(); }).start(); new Thread(() -> { log.debug("begin"); n1.b(); }).start(); } } @Slf4j class Number{ public synchronized void a(){ log.debug("1"); } public synchronized void b(){ log.debug("2"); } }
情况2 : 1s后1 2 或 1s后2 1
@Slf4j public class Test { public static void main(String[] args) throws InterruptedException { Number n1 = new Number(); new Thread(() -> { log.debug("begin"); n1.a(); }).start(); new Thread(() -> { log.debug("begin"); n1.b(); }).start(); } } @Slf4j class Number{ public synchronized void a() throws InterruptedException { Thread.sleep(1000); log.debug("1"); } public synchronized void b(){ log.debug("2"); } }
情况3 : 3 ,1s后 1 2 || 3 , 2 1s后打印1 || 2 , 3 1s后打印1
@Slf4j public class Test { public static void main(String[] args) throws InterruptedException { Number n1 = new Number(); new Thread(() -> { log.debug("begin"); n1.a(); }).start(); new Thread(() -> { log.debug("begin"); n1.b(); }).start(); new Thread(() -> { log.debug("begin"); n1.c(); }).start(); } } @Slf4j class Number{ public synchronized void a() { try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } log.debug("1"); } public synchronized void b(){ log.debug("2"); } public void c(){ log.debug("3"); } }
情况4 : 先2,1s后打印1
@Slf4j public class Test { public static void main(String[] args) throws InterruptedException { Number n1 = new Number(); Number n2 = new Number(); new Thread(() -> { log.debug("begin"); n1.a(); }).start(); new Thread(() -> { log.debug("begin"); n2.b(); }).start(); } } @Slf4j class Number{ public synchronized void a() { try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } log.debug("1"); } public synchronized void b(){ log.debug("2"); } }
情况5 : 先2,1s后打印1
@Slf4j public class Test { public static void main(String[] args) throws InterruptedException { Number n1 = new Number(); new Thread(() -> { log.debug("begin"); n1.a(); }).start(); new Thread(() -> { log.debug("begin"); n1.b(); }).start(); } } @Slf4j class Number{ public static synchronized void a() { // 锁住的是类对象 try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } log.debug("1"); } public synchronized void b(){ log.debug("2"); } }
情况6 : 1s后打印1 后2 || 2 1s后打印1
@Slf4j public class Test { public static void main(String[] args) throws InterruptedException { Number n1 = new Number(); new Thread(() -> { log.debug("begin"); n1.a(); }).start(); new Thread(() -> { log.debug("begin"); n1.b(); }).start(); } } @Slf4j class Number{ public static synchronized void a() { try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } log.debug("1"); } public static synchronized void b(){ log.debug("2"); } }
情况7 : 先2 1s后打印1
import lombok.extern.slf4j.Slf4j; @Slf4j public class Test { public static void main(String[] args) throws InterruptedException { Number n1 = new Number(); Number n2 = new Number(); new Thread(() -> { log.debug("begin"); n1.a(); }).start(); new Thread(() -> { log.debug("begin"); n2.b(); }).start(); } } @Slf4j class Number{ public static synchronized void a() { try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } log.debug("1"); } public synchronized void b(){ log.debug("2"); } }
情况8 : 1s后打印1 后2 || 2 1s后打印1
import lombok.extern.slf4j.Slf4j; @Slf4j public class Test { public static void main(String[] args) throws InterruptedException { Number n1 = new Number(); Number n2 = new Number(); new Thread(() -> { log.debug("begin"); n1.a(); }).start(); new Thread(() -> { log.debug("begin"); n2.b(); }).start(); } } @Slf4j class Number{ public static synchronized void a() { try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } log.debug("1"); } public static synchronized void b(){ log.debug("2"); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。