zoukankan      html  css  js  c++  java
  • 单任务多线程 安全

    线程状态

    线程安全

       如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的

    买票例子

    原理图:

    代码:

    package com.oracle.Demo03;
    
    public class Tickets implements Runnable{
    	//把线程的共享数据做成成员变量
    	private int tickets=100;
    	//锁对象
    	private Object mutex=new Object();
    	public void run() {
    		while(true){
    			//同步代码快解决线程安全问题
    			synchronized (mutex) {
    				if (tickets>0) {
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    					System.out.println(Thread.currentThread().getName()+"售出第"+
    				tickets--+"张票");
    				}
    			}
    			
    		}
    	}
    
    }
    package com.oracle.Demo03;
    
    public class Demo01 {
    
    	public static void main(String[] args) {
    		//创建创建线程任务
    		Tickets03 t=new Tickets03();
    		//创建3个线程对象
    		Thread t1=new Thread(t);
    		Thread t2=new Thread(t);
    		Thread t3=new Thread(t);
    		//开启线程
    		t1.start();
    		t2.start();
    		t3.start();
    	}
    

      不安全原理图

    线程同步(线程安全处理Synchronized)

    线程同步的方式有两种:

      方式1:同步代码块

      方式2:同步方法

    同步代码块: 在代码块声明上 加上synchronized

    同步代码块中的锁对象可以是任意的对象;但多个线程时,要使用同一个锁对象才能够保证线程安全。

    public class Ticket implements Runnable {
    	//共100票
    	int ticket = 100;
    	//定义锁对象
    	Object lock = new Object();
    	@Override
    	public void run() {
    		//模拟卖票
    		while(true){
    			//同步代码块
    			synchronized (lock){
    				if (ticket > 0) {
    					//模拟电影选坐的操作
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					System.out.println(Thread.currentThread().getName() + "正在卖票:" + ticket--);
    				}
    			}
    		}
    	}
    

      

    同步方法

      同步方法:在方法声明上加上synchronized    

      同步方法中的锁对象是 this

    package com.oracle.Demo03;
    
    public class Tickets02 implements Runnable {
    	// 把线程的共享数据做成成员变量
    	private int tickets = 100;
    
    	public void run() {
    		while (true) {
    
    			sale();
    
    		}
    	}
    	//同步方法
    	//StringBuffer 慢 所有方法都是同步方法 安全
    	//StringBuilder 快  所有方法都是非同步方法   不安全
    	public synchronized void sale(){
    		if (tickets > 0) {
    			try {
    				Thread.sleep(10);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			System.out.println(Thread.currentThread().getName() + "售出第" + tickets-- + "张票");
    
    		}
    	}
    
    }
    package com.oracle.Demo03;
    
    public class Demo01 {
    
    	public static void main(String[] args) {
    		//创建创建线程任务
    		Tickets03 t=new Tickets03();
    		//创建3个线程对象
    		Thread t1=new Thread(t);
    		Thread t2=new Thread(t);
    		Thread t3=new Thread(t);
    		//开启线程
    		t1.start();
    		t2.start();
    		t3.start();
    	}
    
    }
    

      注意:StringBuffer 慢 所有方法都是同步方法 安全
            StringBuilder 快  所有方法都是非同步方法   不安全

    Lock接口

    Lock提供了一个更加面对对象的锁,在该锁中提供了更多的操作锁的功能

    package com.oracle.Demo03;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Tickets03 implements Runnable{
    	//把线程的共享数据做成成员变量
    	private int tickets=100;
    	private Lock lock=new ReentrantLock();
    	private Object mutex=new Object();
    	public void run() {
    		while(true){
    			lock.lock();
    				if (tickets>0) {
    					try {
    						Thread.sleep(10);
    					} catch (InterruptedException e) {
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    					System.out.println(Thread.currentThread().getName()+"售出第"+
    				tickets--+"张票");
    				lock.unlock();
    			}
    			
    		}
    	}
    
    }
    

      

  • 相关阅读:
    【Mybatis plus 3.2】怎么操作?看看我!(update、limit、between)
    #1024程序员节# 节日快乐
    ERROR: ...hbase.PleaseHoldException: Master is initializing
    【Flume】安装与测试
    【Storm】与Hadoop的区别
    【Storm】核心组件nimbus、supervisor、worker、executor、task
    LeetCode124:Binary Tree Maximum Path Sum
    LeetCode123:Best Time to Buy and Sell Stock III
    LeetCode122:Best Time to Buy and Sell Stock II
    LeetCode121:Best Time to Buy and Sell Stock
  • 原文地址:https://www.cnblogs.com/zqy6666/p/12320590.html
Copyright © 2011-2022 走看看