主要是针对 synchronized
。
加锁对象是谁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package com.redisc;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.Test") 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.decrement(); } }); Thread t2 = new Thread(() -> { for (int i = 0; i < 5000; i++) { room.increment(); } });
t1.start(); t2.start(); t1.join(); t2.join();
log.debug("{}", room.getCounter()); } }
class Room { private int counter = 0;
public synchronized void increment() { counter++; }
public synchronized void decrement() { counter--; }
public synchronized int getCounter() { return this.counter; } }
|
加锁对象是 Room 的 this。
可以 1 优先吗
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.redisc;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j(topic = "c.Test") public class Test {
public static void main(String[] args) throws InterruptedException { Room room = new Room(); Thread t1 = new Thread(room::decrement); Thread t2 = new Thread(() -> { try { room.increment(); } catch (InterruptedException e) { e.printStackTrace(); } });
t1.start(); t2.start(); t1.join(); t2.join();
log.debug("{}", room.getCounter()); } }
@Slf4j(topic = "c.Room") class Room { private int counter = 0;
public synchronized void increment() throws InterruptedException { TimeUnit.SECONDS.sleep(1); counter++; log.debug("1"); }
public synchronized void decrement() { counter--; log.debug("2"); }
public synchronized int getCounter() { return this.counter; } }
|
答案有机会出现 1
先于 2
的情况。因为,虽然,1
中有 sleep
,但是,cpu
给两个线程谁先上锁是随机的。
c 方法有互斥吗
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.redisc;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j(topic = "c.Test") public class Test {
public static void main(String[] args) throws InterruptedException { Room room = new Room(); Thread t1 = new Thread(()->{ try { room.a(); } catch (InterruptedException e) { e.printStackTrace(); } }); Thread t2 = new Thread(()->{ room.b(); }); Thread t3 = new Thread(()->{ room.c(); });
t1.start(); t2.start(); t3.start(); } }
@Slf4j(topic = "c.Room") class Room {
public synchronized void a() throws InterruptedException { TimeUnit.SECONDS.sleep(1); log.debug("1"); }
public synchronized void b() { log.debug("2"); }
public void c() { log.debug("3"); }
}
|
c
没有互斥效果。
room1 和 room2 互斥吗
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package com.redisc;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j(topic = "c.Test") public class Test {
public static void main(String[] args) throws InterruptedException { Room room1 = new Room(); Room room2 = new Room(); Thread t2 = new Thread(() -> { room1.b(); }); Thread t3 = new Thread(() -> { room2.c(); });
t2.start(); t3.start(); } }
@Slf4j(topic = "c.Room") class Room {
public synchronized void b() { log.debug("2"); }
public synchronized void c() { log.debug("3"); }
}
|
不互斥,分属于两个对象。
后面的题目都很简单,只要把 java | synchronized 对象锁 看懂就好了。