• 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是类锁,锁住这个类

  • 相关阅读:
    ORACLE错误笔记
    SQL-考试各科目的成绩以及各科目的参与考试次数
    MySql有几条更新sql不能执行时的解决方案
    面试中常遇到的算法面试题
    MySql绿色版安装教程
    Javaweb
    关于JavaWeb不使用框架上传文件的简单实现
    SSM框架
    数据库
    J2SE
  • 原文地址:https://www.cnblogs.com/Donnnnnn/p/9060060.html
Copyright © 2020-2023  润新知