zoukankan      html  css  js  c++  java
  • Java多线程基础之线程同步与锁定

    线程同步与锁定

    由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突严重的这个问题,Java语言提供了专门的机制以解决这类冲突,有效避免了同一个数据对象被多个线程同时访问,由于我们可以通过private关键字来保证数据对象只能被方法访问,所以我们针对方法提出一整套机制,这套机制就是sychronized关键字;

    sychronized:

    HashTable 和StringBuffer底部均有使用 同步代码或同步块;

     * 一:同步块(sychronized(this|.class|引用类型)

    package Tread;
    
    public class Demo  {
    	public static void main(String[] args) {
    		Web12306 wb = new Web12306();
    		Thread t1 = new Thread(wb, "黄牛");
    		Thread t2 = new Thread(wb, "黄牛2");
    		Thread t3 = new Thread(wb, "工程师");
    		t1.start();
    		t2.start();
    		t3.start();
    	}
    }
    class Web12306 implements Runnable {
    	int num = 10;
    	private boolean flag = true;
    
    	@Override
    	public void run() {
    		while (true) {
    			test1();
    		}
    
    	}
         // 线程不安全
    	public void test1() {
    		if(num<=0) {
    			flag=false;
    			return;
    		}
    		try {
    			Thread.sleep(500);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		System.out.println(Thread.currentThread().getName()+"抢到了"+num--+"票");
    	}
         // 同步方法
    	public synchronized  void test2() {
    		if(num<=0) {
    			flag=false;
    			return;
    		}
    		try {
    			Thread.sleep(500);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		System.out.println(Thread.currentThread().getName()+"抢到了"+num--+"票");
    	}
    
       //锁定this对象
               public void test2() {
    		synchronized (this) {
    		if (num <= 0) {
    			flag = false;
    			return;
    		}
    		try {
    			Thread.sleep(500);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		System.out.println(Thread.currentThread().getName() + "抢到了" + num-- + "票");
    	}
    	}
    
    
    }
    

      / 锁定范围不正确与锁定资源不正确,均会造成线程不安全,错误代码实例

    	public void test2() {
    		if (num <= 0) {
    			flag = false;
    			return;
    		}
    		synchronized (this) {
    		try {
    			Thread.sleep(500);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		System.out.println(Thread.currentThread().getName() + "抢到了" + num-- + "票");
    	}
    	}
    	  public void test2() {
    		synchronized ((Integer)num) {
    		if (num <= 0) {
    			flag = false;
    			return;
    		}
    		
    		try {
    			Thread.sleep(500);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		System.out.println(Thread.currentThread().getName() + "抢到了" + num-- + "票");
    	}
    	}
    

      锁定.class对象

    单例设计模式

    单例设计模式: 确保一个类只有一个对象
     *   懒汉式
     *  1.构造器私有化,避免外部直接创建对象
     *  2.声明一个私有的静态变量
     *  3.创建一个对外公共的静态方法访问该变量,如果该变量没有对象,创建该对象
     

    package Tread;
    
    //单例设计模式:确保一个类只有一个对象
    public class SynDemo {
    	public static void main(String[] args) {
    		Jvmthread jvm1 = new Jvmthread(100);
    		Jvmthread jvm2 = new Jvmthread(500);
    		new Thread(jvm1).start();
    		new Thread(jvm2).start();
    	}
    }
    
    class Jvmthread implements Runnable {
    	private long time;
    
    	public Jvmthread(long time) {
    		super();
    		this.time = time;
    	}
    
    	@Override
    	public void run() {
    		System.out.println(Thread.currentThread().getName() + "------>" + Jvm.getInstance(time));
    
    	}
    
    }
    /**
     * 单例设计模式: 确保一个类只有一个对象
     *  懒汉式 
     *  1.构造器私有化,避免外部直接创建对象 
     *  2.声明一个私有的静态变量
     * 3.创建一个对外公共的静态方法访问该变量,如果该变量没有对象,创建该对象
     */
    class Jvm {
    	private static Jvm instance = null;
    
    	private Jvm() {
    
    	}
    
    	// 两种方法,一种锁住方法,一种锁住.class文件,注意:静态方法不能存在this对象,所以不能锁住this
    	public static Jvm getInstance(long time) {
    		if (null == instance) {
    			try {
    				Thread.sleep(time);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			instance = new Jvm();
    		}
    		return instance;
    	}
    
    	// 提高效率:双重检查 已经有对象,其他线程不用再等待锁
    	public static Jvm getInstance2(long time) {
    		if (null == instance) {
    		synchronized (Jvm.class) {
    			if (null == instance) {
    				try {
    					Thread.sleep(time);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				instance = new Jvm();
    			}
    		}
    		}
    		return instance;
    	}
    
    }
    

      饿汉式
     * 1.构造器私有化,避免外部直接创建对象
     * 2.声明一个私有的静态变量,同时创建该对象
     * 3.创建一个对外公共的静态方法访问该变量,如果该变量没有对象,创建该对象

    package Tread;
    
    /*****
     * 饿汉式 
     * 1.构造器私有化,避免外部直接创建对象 
     * 2.声明一个私有的静态变量,同时创建该对象
     * 3.创建一个对外公共的静态方法访问该变量,如果该变量没有对象,创建该对象
     */
    public class MyJvM {
    	private static MyJvM instance=new MyJvM();
    	private MyJvM () {
    
    	}
    	public static MyJvM  getInstance(long time) {
    		return instance;
    	}
    }
    
    /**优化写法
     * 类在使用的时候才加载,延缓加载时间
     *
     */
    class MyJvM3 {
    	private static class Jvmholder {
    		private static MyJvM3 instance = new MyJvM3();
    	}
    
    	private MyJvM3() {
    
    	}
    
    	public static MyJvM3 getInstance() {
    		return Jvmholder.instance;
    	}
    
    }
    

      

  • 相关阅读:
    每天一道leetcode 搜索旋转排序数组(二分法)
    每天一道leetcode 统计重复个数(循环节)
    python3 简单web目录扫描脚本(后续更新完整)
    每天一道leetcode 盛最多水的容器 (双指针)
    python3 语法学习 类和继承
    python3 语法学习 文件操作及os方法
    python3 语法学习 输入输出美观
    TCP/IP 协议:IP 协议
    TCP/IP 协议:链路层概述
    Http权威指南(二)---读书笔记
  • 原文地址:https://www.cnblogs.com/yjxs/p/9848555.html
Copyright © 2011-2022 走看看