zoukankan      html  css  js  c++  java
  • 并发编程基础之对象锁与类锁

    一:通常情况下,在遇到并发问题时,我们首先想到的时在方法上面加synchronized关键字,或者

    1:将可能会产生并发问题的代码使用synchronized修饰,这样访问该段代码的时候,线程就会一个一个排队

    访问,这时创建的锁一般为对象锁。

    如果创建两个实例,分别依附在两个线程上,那么会出现什么情况呢?

    /**
     * 
     */
    package com.day1;
    
    /**
     * @author Administrator 多线程操作
     */
    public class MultiThread {
    
    	private int num = 0;
    
    	public synchronized void printNum(String tag) {
    		if ("a".equals(tag)) {
    			num = 100;
    			System.out.println("tag=" + tag + " num=" + num);
    			try {
    				Thread.sleep(1000L);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		} else {
    			num = 200;
    			System.out.println("tag=" + tag + " num=" + num);
    		}
    	}
    
    	public static void main(String[] args) {
    		final MultiThread thread1 = new MultiThread();
    		final MultiThread thread2 = new MultiThread();
    		new Thread() {
    			public void run() {
    				thread1.printNum("a");
    			}
    		}.start();
    		new Thread() {
    			public void run() {
    				thread2.printNum("b");
    			}
    		}.start();
    
    	}
    }
    

     运行结果:

    tag=a num=100
    tag=b num=200
    

     运行结束后,等待一秒钟,然后虚拟机停止运行。

    两个线程分别运行不同的实例,其实他们之间没有任何关系,各自运行各自的,因为锁是两个,就是两个对象锁,

    不会导致另一个线程阻塞。

    :2:如果将成员变量修改成static的,会怎样呢?

    private static int num = 0;
    

     static修饰的静态变量,属于类,由该类创建的实例共享这个的变量的值。

    3:如果将printNum方法修改为static方法,打印结果会怎样?

    首先打印tag=a num=100,然后停顿1s,再打印tag=b num=200

    可以看出这里产生了阻塞,因为同步方法是static的,所以该锁为类锁,不同的实例访问该方法时产生了

    阻塞,第一个线程先进入,释放锁后第二个线程再进入。

  • 相关阅读:
    p1706 全排列
    2089烤鸡(类似于选数问题)
    1036选数
    bfs
    A-E
    A-3
    百题A-2
    百题A-1
    二级概念题
    随记
  • 原文地址:https://www.cnblogs.com/warrior4236/p/7157971.html
Copyright © 2011-2022 走看看