• Java多线程笔记1


    1. synchronized (obj)

        private int count = 10;
        private Object obj = new Object();
    
        public void sub() {
            synchronized (obj) {
                count--;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    上述代码中 synchronized 锁定的是 obj 这个对象;

    2. synchronized (this)

        private int count = 10;
    
        public void sub() {
            synchronized (this) {
                count--;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    上述代码中 synchronized 锁定的是 当前对象;

        private int count = 10;
        private Object obj = new Object();
    
        public synchronized void sub() {
            count--;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在方法上加锁,锁定的依然是当前对象,所以这种写法等同于上面;不过没有上面的写法灵活。

    3. synchronized static function

        private static int count = 10;
    
        public synchronized static void sub() {
            count--;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在静态方法上加锁,锁定的是当前类的产品是一类对象;

        public static void sub2() {
            synchronized (Demo1.class) {
                count--;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    等同于上诉写法;

    4. synchronized 是一种可重入锁

        public synchronized  void m1() {
            count--;
            m2(); // 可重入
        }
    
        public synchronized  void m2() {
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5. 模拟死锁

    6. 子类同步方法可以调用父类的同步方法 (可重入的另一种方式)

    7. synchronized同步锁在遇到异常后会自动释放

    8. volatile 内存可见性,不保证原子性

    可以配合Atomic类使用;如 AtomicInteger

    注意:Atomic类的多个方法同时使用时不保证原子性,单独使用时才能保证原子性

    9. synchronized 也可以保证内存可见性,同时可以保证原子性

    10. 不用以字符串常量作为锁定对象

        String str1 = "Hello";
        String str2 = "Hello";
    
        public void m1() {
            synchronized (str1) {
                count--;
            }
    
        }
    
        public void m2() {
            synchronized (str2) {
                count--;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    其实 str1 和 str2 底层是同一个对象;

    11. wait() 会释放锁,而 notify() 和 sleep() 不会释放锁

    public class MyContainer4 {
    
    	//添加volatile,使t2能够得到通知
    	volatile List lists = new ArrayList();
    
    	public void add(Object o) {
    		lists.add(o);
    	}
    
    	public int size() {
    		return lists.size();
    	}
    	
    	public static void main(String[] args) {
    		MyContainer4 c = new MyContainer4();
    		
    		final Object lock = new Object();
    		
    		new Thread(() -> {
    			synchronized(lock) {
    				System.out.println("t2启动");
    				if(c.size() != 5) {
    					try {
    						lock.wait();
    					} catch (InterruptedException e) {
    					}
    				}
    				System.out.println("t2 结束");
    				//通知t1继续执行
    				lock.notify();
    			}
    			
    		}, "t2").start();
    		
    		try {
    			TimeUnit.SECONDS.sleep(1);
    		} catch (InterruptedException e1) {
    		}
    
    		new Thread(() -> {
    			System.out.println("t1启动");
    			synchronized(lock) {
    				for(int i=0; i<10; i++) {
    					c.add(new Object());
    					System.out.println("add " + i);
    					
    					if(c.size() == 5) {
    						lock.notify();
    						//释放锁,让t2得以执行
    						try {
    							lock.wait();
    						} catch (InterruptedException e) {
    						}
    					}
    					
    					try {
    						TimeUnit.SECONDS.sleep(1);
    					} catch (InterruptedException e) {
    					}
    				}
    			}
    		}, "t1").start();
    	}
    }
    
    • 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
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    12. join 的用法

    	// https://www.cnblogs.com/duanxz/p/5038471.html
        public static void main(String[] args) {
            long start = System.currentTimeMillis();
            Object obj = new Object();
    
            Thread thread1 = new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " start...");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
    
                //LockSupport.park();
                synchronized (obj) {
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                System.out.println(Thread.currentThread().getName() + " over");
            }, "thread1");
            Thread thread2 = new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " start,,,");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
    
                //LockSupport.unpark(thread1);
                synchronized (obj) {
                    obj.notifyAll();
                }
                System.out.println(Thread.currentThread().getName() + " over");
            }, "thread2");
    
            thread1.start();
            thread2.start();
            try {
                thread1.join();
                thread2.join();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
    
            System.out.println(System.currentTimeMillis() - start);
        }
    
    • 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
    • 49
  • 相关阅读:
    [附源码]java毕业设计小说网站的设计与实现1
    Tensorflow2.0使用model.fit训练,查看每一层的参数数值以及输出
    JAVA实现水仙花数
    反转链表问题的递归解法
    使用Django框架快速搭建个人网站
    爬虫逆向实战(33)-某联社数据(webpack)
    mysql的数据库、表、字段、数据操作sql
    常用软件安装
    冷热电气多能互补的微能源网鲁棒优化调度附Matlab代码
    Docker—概述与安装
  • 原文地址:https://blog.csdn.net/u013837825/article/details/126495892