zoukankan      html  css  js  c++  java
  • 线程同步synchronized

    一Java规划共享多个线程之间数据的能力
    当线程以异步方式訪问共享数据时。有时候是不安全的或者不和逻辑的。

    比方卖火车票。同一时刻一个线程在读取数据,另外一个线程在处理数据,当处理数据的线程没有等到读取数据的线程读取完成就去处理数据,必定得到错误的处理结果。


    卖火车票Demo:
    class MyThread implements Runnable{
    	private int ticket = 5 ;	// 如果一共同拥有5张票
    	public void run(){
    		for(int i=0;i<100;i++){
    			if(ticket>0){	// 还有票
    				try{
    					Thread.sleep(300) ;	// 增加延迟
    				}catch(InterruptedException e){
    					e.printStackTrace() ;
    				}
    				System.out.println("卖票:ticket = " + ticket-- );
    			}
    		}
    	}
    };
    public class SyncDemo01{
    	public static void main(String args[]){
    		MyThread mt = new MyThread() ;	// 定义线程对象
    		Thread t1 = new Thread(mt) ;	// 定义Thread对象
    		Thread t2 = new Thread(mt) ;	// 定义Thread对象
    		Thread t3 = new Thread(mt) ;	// 定义Thread对象
    		t1.start() ;
    		t2.start() ;
    		t3.start() ;
    	}
    };
    执行有可能出现下面结果:
    .......
    卖票:ticket=1
    卖票:ticket=0
    卖票:ticket=-1

    Java 编程语言提供了一种简单的机制来防止发生这样的覆盖。

    每一个对象在执行时都有一个关联的锁。这个锁可通过为方法加入keyword synchronized 来获得。同步有两种方式:同步块和同步方法


    同步块:对易发生冲突的语句块加锁

    class MyThread implements Runnable{
    	private int ticket = 5 ;	// 如果一共同拥有5张票
    	public void run(){
    		for(int i=0;i<100;i++){
    			synchronized(this){	// 要对当前对象进行同步
    				if(ticket>0){	// 还有票
    					try{
    						Thread.sleep(300) ;	// 增加延迟
    					}catch(InterruptedException e){
    						e.printStackTrace() ;
    					}
    					System.out.println("卖票:ticket = " + ticket-- );
    				}
    			}
    		}
    	}
    };
    public class SyncDemo02{
    	public static void main(String args[]){
    		MyThread mt = new MyThread() ;	// 定义线程对象
    		Thread t1 = new Thread(mt) ;	// 定义Thread对象
    		Thread t2 = new Thread(mt) ;	// 定义Thread对象
    		Thread t3 = new Thread(mt) ;	// 定义Thread对象
    		t1.start() ;
    		t2.start() ;
    		t3.start() ;
    	}
    };


    同步方法:对易发生冲突的方法块加锁

    class MyThread implements Runnable{
    	private int ticket = 5 ;	// 如果一共同拥有5张票
    	public void run(){
    		for(int i=0;i<100;i++){
    			this.sale() ;	// 调用同步方法
    		}
    	}
    	public synchronized void sale(){	// 声明同步方法
    		if(ticket>0){	// 还有票
    			try{
    				Thread.sleep(300) ;	// 增加延迟
    			}catch(InterruptedException e){
    				e.printStackTrace() ;
    			}
    			System.out.println("卖票:ticket = " + ticket-- );
    		}
    
    	}
    };
    public class SyncDemo03{
    	public static void main(String args[]){
    		MyThread mt = new MyThread() ;	// 定义线程对象
    		Thread t1 = new Thread(mt) ;	// 定义Thread对象
    		Thread t2 = new Thread(mt) ;	// 定义Thread对象
    		Thread t3 = new Thread(mt) ;	// 定义Thread对象
    		t1.start() ;
    		t2.start() ;
    		t3.start() ;
    	}
    };






    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    vfs:结构体对象
    vfs:open.c 源码学习
    Linux direct io使用例子
    GPU安装小结
    tensorflow scope的作用
    tensorflow 一维卷积 tf.layers.conv1()使用
    tensorflow 的tf.where详解
    tensorflow 的tf.split函数的用法
    tensorflow 添加一个全连接层
    tensorflow 计算均值和方差
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4869934.html
Copyright © 2011-2022 走看看