方法上的 synchronized
与使用synchronized(X)等效
class Test{
public synchronized void test() {
}
}
等价于
class Test{
public void test() {
synchronized(this) {
}
}
}
class Test{
public synchronized static void test() {
}
}
等价于
class Test{
public static void test() {
synchronized(Test.class) {
}
}
}
不加 synchronized 的方法
不加 synchronzied 的方法就好比不遵守规则的人,不去老实排队(好比翻窗户进去的)
“线程八锁”
其实就是考察 synchronized 锁住的是哪个对象
情况1:12 或 21
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
// 不能确定谁先执行了,因为感觉像同时打开的线程
new Thread(()->{
n1.a(); }).start(); // 在多核CPU下,主线程会把这几个线程打开,但是即使打开了,仍然会被上锁导致无法运行
new Thread(()->{
n1.b(); }).start();
}
情况2:1s后12,或 2 1s后 1
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n1.b(); }).start(); // 如果线程1先启动并sleep了,但是不会释放锁,即使2当前被分到了线程时间片,仍然没法执行
}
情况3:3 1s 12 或 23 1s 1 或 32 1s 1
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
// 有互斥效果
log.debug("2"); // 执行完马上释放锁了
}
public void c() {
log.debug("3");
}
}
public static void main(String[] args) {
Number n1 = new Number();
// 主线程几乎同时打开3个线程
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n1.b(); }).start();
new Thread(()->{
n1.c(); }).start();
}
情况4:2 1s 后 1
@Slf4j(topic = "c.Number")
class Number{
public synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n2.b(); }).start();
}
情况5:2 1s 后 1,锁住的类对象和实例对象是不同的对象,同时执行的,在多核的情况下,一定是2先打印出来
@Slf4j(topic = "c.Number")
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n1.b(); }).start();
}
情况6:1s 后12, 或 2 1s后 1, 同时锁住类对象
@Slf4j(topic = "c.Number")
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public static synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n1.b(); }).start();
}
情况7:2 1s 后 1,锁不同的对象,同时执行,先打印出2
@Slf4j(topic = "c.Number")
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n2.b(); }).start();
}
情况8:1s 后12, 或 2 1s后 1 ,锁住的同一个Number.class对象
@Slf4j(topic = "c.Number")
class Number{
public static synchronized void a() {
sleep(1);
log.debug("1");
}
public static synchronized void b() {
log.debug("2");
}
}
public static void main(String[] args) {
Number n1 = new Number();
Number n2 = new Number();
new Thread(()->{
n1.a(); }).start();
new Thread(()->{
n2.b(); }).start();
}