zoukankan      html  css  js  c++  java
  • Java并发编程_synchronized关键字的用法(一)

     synchronized:意思是 同步,也就是 共享资源

    Synchronized修饰方法:对象锁

    Static Synchronized修饰方法:类锁

    下面代码手动敲一遍,就会理解

     一、Synchronized修饰方法

    1、一个对象,启动多个线程,竞争一把对象锁

    package sync;
    /*
     * 一个对象,启动多个线程,竞争一把对象锁
     */
    public class MyThread extends Thread{
    
    	private int count = 5;
    	
    	public synchronized void run() {
    		count--;
    		System.out.println(this.currentThread().getName() + " count = " + count);
    	}
    	
    	public static void main(String[] args) {
    		//新建一个对象
    		MyThread myThread = new MyThread();
    		//启动多个线程
    		Thread t1 = new Thread(myThread,"t1");
    		Thread t2 = new Thread(myThread,"t2");
    		Thread t3 = new Thread(myThread,"t3");
    		Thread t4 = new Thread(myThread,"t4");
    		Thread t5 = new Thread(myThread,"t5");
    		t1.start();
    		t2.start();
    		t3.start();
    		t4.start();
    		t5.start();
    	}
    }
    

    输出结果:

    t1 count = 4
    t4 count = 3
    t5 count = 2
    t3 count = 1
    t2 count = 0
    

    这五个线程,哪个先执行,哪个后执行,要看CPU调度

    2、多个对象,启动多个线程,竞争多把对象锁

    package sync;
    
    public class MultiThread {
    
    	private int num = 0;
    	
    	public synchronized void printNum(String tag) {
    		try {
    			if(tag.equals("a")) {
    				num = 100;
    				System.out.println("tag a , set num over!");
    				Thread.sleep(1000);
    				System.out.println("tag " + tag + ", num = " + num);
    			}else {
    				num = 200;
    				System.out.println("tag b , set num over!");
    				Thread.sleep(1000);
    				System.out.println("tag " + tag + ", num = " + num);
    			}
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    	
    	public static void main(String[] args) {
    		//新建两个对象m1 、m2
    		MultiThread m1 = new MultiThread();
    		MultiThread m2 = new MultiThread();
    		
    		//新建第一个线程,调用m1对象的printNum()方法
    		Thread t1 = new Thread(new Runnable() {
    			@Override
    			public void run() {
    				m1.printNum("a");
    			}
    			
    		});
    		//新建第二个线程,调用m2对象的printNum()方法
    		Thread t2 = new Thread(new Runnable() {
    			@Override
    			public void run() {
    				m2.printNum("b");
    			}
    		});
    		//同时启动两个线程
    		t1.start();
    		t2.start();
    		
    		//是先执行完线程t1,再执行线程t2吗?
    	}
    }

    输出结果:

    tag b , set num over!
    tag a , set num over!
    tag b, num = 200
    tag a, num = 100
    

      

    可以看到,线程t1和线程t2是同时执行,两个线程互不影响,独立执行,因此输出结果自然不分先后.

    第一个对象m1访问后,锁住m1这个对象;然后,第二个对象m2继续访问,不会被m1锁影响到。

    结论:

    (1)synchronized是对象锁,多个对象多个锁,锁的是对象。

    (2)而不是把一个方法或者一个类当作锁(一个Class类可以new多个对象嘛)

    二、Static Synchronized修饰方法

    在静态方法上加上synchronized关键字,表示锁定class类,类一级别的锁(独占class类)

    无论new多少个对象去访问该静态synchronized方法,都要排队一个个访问,竞争同一把锁(class这个锁)

    package sync;
    
    public class MultiThread {
    
    	private static int num = 0;
    	
    	public static synchronized void printNum(String tag) {
    		try {
    			if(tag.equals("a")) {
    				num = 100;
    				System.out.println("tag a , set num over!");
    				Thread.sleep(1000);
    				System.out.println("tag " + tag + ", num = " + num);
    			}else {
    				num = 200;
    				System.out.println("tag b , set num over!");
    				Thread.sleep(1000);
    				System.out.println("tag " + tag + ", num = " + num);
    			}
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    	
    	public static void main(String[] args) {
    		//新建两个对象m1 、m2
    		MultiThread m1 = new MultiThread();
    		MultiThread m2 = new MultiThread();
    		
    		//新建第一个线程,调用m1对象的printNum()方法
    		Thread t1 = new Thread(new Runnable() {
    			@Override
    			public void run() {
    				m1.printNum("a");
    			}
    			
    		});
    		//新建第二个线程,调用m2对象的printNum()方法
    		Thread t2 = new Thread(new Runnable() {
    			@Override
    			public void run() {
    				m2.printNum("b");
    			}
    		});
    		//同时启动两个线程
    		t1.start();
    		t2.start();
    		
    		//是先执行完线程t1,再执行线程t2吗?
    	}
    }
    

      

    输出结果:

    tag b , set num over!
    tag b, num = 200
    tag a , set num over!
    tag a, num = 100
    

      

    可以看到:

    先执行完一个线程b,再执行下一个线程a

    结论:

    (1)static synchronized是类锁,锁住这个类

  • 相关阅读:
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    asp.net session对象的持久化
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    小白也能看懂的约瑟夫环问题
  • 原文地址:https://www.cnblogs.com/Donnnnnn/p/9060060.html
Copyright © 2011-2022 走看看