• Java入门——同步与死锁


    Java入门——同步与死锁


     

    同步

      解决资源共享的同步操作,可以使用同步代码块和同步方法两种方法完成。

     

     1 package Sep19;
     2 
     3 class MyThread implements Runnable{
     4     private int ticket=5;
     5     public void run(){//覆写run方法
     6         for(int i=0;i<100;i++){
     7             if (ticket>0){
     8                 try{
     9                     Thread.sleep(3000);
    10                 }catch(InterruptedException e){
    11                     e.printStackTrace();
    12                 }
    13                 System.out.println("卖票:ticket="+ticket--);
    14             }
    15         }
    16     }
    17 }
    18 public class SyncDemo01{
    19     public static void main(String[] args) {
    20         MyThread mt=new MyThread();
    21         Thread t1=new Thread(mt);
    22         Thread t2=new Thread(mt);
    23         Thread t3=new Thread(mt);
    24         t1.start();
    25         t2.start();
    26         t3.start();
    27     }
    28 }
    卖票:ticket=5
    卖票:ticket=3
    卖票:ticket=4
    卖票:ticket=2
    卖票:ticket=1
    卖票:ticket=0

    同步代码块

      在所需要同步的代码前加关键字:synchronized(同步对象){需要同步的代码;}

    同步方法:

      可以使用synchronized关键字声明同步方法。


    死锁

      过多的同步操作也可能产生死锁的现象,两个线程都在彼此等待对方的执行完成,这样,线程就会无法继续向下执行,从而造成了死锁的现象。


    线程的经典案例——生产者与消费者

    package Sep19;
    class Info{
    	private String name="李兴华";
    	private String content="JAVA讲师";
    	public void setName(String name) {
    		this.name = name;
    	}
    	public void setContent(String content) {
    		this.content = content;
    	}
    	public String getName() {
    		return name;
    	}
    	public String getContent() {
    		return content;
    	}
    }
    
    class Producer implements Runnable{
    	private Info info=null;
    	public Producer(Info info){
    		this.info=info;
    	}
    	public void run() {
    		boolean flag=false;
    		for (int i = 0; i < 50; i++) {
    			if(flag){
    				this.info.setName("李兴华");
    				try {
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				this.info.setContent("JAVA讲师");
    				flag=false;
    			}else{
    				this.info.setName("mldn");
    				try {
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				this.info.setContent("www.mldn.java.com");
    				flag=true;
    			}
    		}
    	}
    }
    
    class Consumer implements Runnable{
    	private Info info=null;
    	public Consumer(Info info){
    		this.info=info;
    	}
    	public void run() {
    		for (int i = 0; i < 50; i++) {
    			try {
    				Thread.sleep(100);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			System.out.println(this.info.getName()+"------->"+this.info.getContent());
    		}
    	}
    	
    }
    public class ThreadCaseDemo01 {
    	public static void main(String[] args) {
    		Info i=new Info();
    		Producer p=new Producer(i);
    		Consumer con=new Consumer(i);
    		new Thread(p).start();
    		new Thread(con).start();
    	}
    }
    

      

    李兴华------->www.mldn.java.com
    李兴华------->www.mldn.java.com
    mldn------->JAVA讲师
    mldn------->JAVA讲师
    李兴华------->www.mldn.java.com
    李兴华------->JAVA讲师
    mldn------->www.mldn.java.com
    mldn------->JAVA讲师
    mldn------->www.mldn.java.com
    mldn------->JAVA讲师
    mldn------->www.mldn.java.com
    mldn------->JAVA讲师
    李兴华------->www.mldn.java.com
    李兴华------->JAVA讲师
    李兴华------->www.mldn.java.com
    mldn------->JAVA讲师
    mldn------->www.mldn.java.com
    李兴华------->www.mldn.java.com
    李兴华------->www.mldn.java.com
    李兴华------->JAVA讲师
    李兴华------->www.mldn.java.com
    mldn------->JAVA讲师
    李兴华------->www.mldn.java.com
    mldn------->JAVA讲师
    李兴华------->www.mldn.java.com
    mldn------->JAVA讲师
    mldn------->www.mldn.java.com
    李兴华------->JAVA讲师
    mldn------->www.mldn.java.com
    mldn------->JAVA讲师
    李兴华------->www.mldn.java.com
    mldn------->JAVA讲师
    mldn------->www.mldn.java.com
    mldn------->JAVA讲师
    李兴华------->www.mldn.java.com
    mldn------->JAVA讲师
    mldn------->www.mldn.java.com
    李兴华------->JAVA讲师
    mldn------->www.mldn.java.com
    李兴华------->JAVA讲师
    李兴华------->www.mldn.java.com
    mldn------->JAVA讲师
    李兴华------->www.mldn.java.com
    mldn------->JAVA讲师
    mldn------->www.mldn.java.com
    mldn------->JAVA讲师
    mldn------->www.mldn.java.com
    mldn------->JAVA讲师
    李兴华------->www.mldn.java.com
    李兴华------->JAVA讲师
    

      本代码出现了重复生产和姓名内容不匹配的现象,需要加入同步,也就是说把setName和setContent设置为在同一个代码块中完成,解决其错位问题。利用Obeject类中等待唤醒机制,的解决错位问题。

    package Sep19;
    class Info{
    	private String name="李兴华";
    	private String content="JAVA讲师";
    	private boolean flag=false; 
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public String getContent() {
    		return content;
    	}
    
    	public void setContent(String content) {
    		this.content = content;
    	}
    
    	public synchronized void set(String name,String content){
    		if(!flag){
    			try {
    				super.wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		this.setName(name);
    		try {
    			Thread.sleep(300);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		this.setContent(content);
    		flag=false;
    		super.notify();
    	}
    	
    	public synchronized void get(){
    		try {
    			Thread.sleep(300);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		System.out.println(this.getName()+"----->"+this.getContent());
    		flag=false;
    		super.notify();
    	}
    }
    
    class Producer implements Runnable{
    	private Info info=null;
    	public Producer(Info info){
    		this.info=info;
    	}
    	public void run() {
    		boolean flag=false;
    		for (int i = 0; i < 50; i++) {
    			if(flag){
    				
    				this.info.set("李兴华","JAVA讲师");
    				flag=false;
    			}else{
    				
    				this.info.set("mldn","www.mldn.java.com");
    				flag=true;
    			}
    		}
    	}
    }
    
    class Consumer implements Runnable{
    	private Info info=null;
    	public Consumer(Info info){
    		this.info=info;
    	}
    	public void run() {
    		for (int i = 0; i < 50; i++) {
    			try {
    				Thread.sleep(100);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    			this.info.get();
    		}
    	}
    	
    }
    public class ThreadCaseDemo01 {
    	public static void main(String[] args) {
    		Info i=new Info();
    		Producer p=new Producer(i);
    		Consumer con=new Consumer(i);
    		new Thread(p).start();
    		new Thread(con).start();
    	}
    }
    

      

    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    mldn----->www.mldn.java.com
    李兴华----->JAVA讲师
    

      

  • 相关阅读:
    【Nginx】使用Nginx做反向代理时,关于被代理服务器相应的超时设置
    【Quartz】配置最简单的集群
    【Quartz】将定时任务持久化到数据库
    【Quartz】Quartz的搭建、应用(单独使用Quartz)
    【Linux】用grep在文档中查找内容
    【Linux】方便的SecureCRT文件上传、下载命令
    【MySQL】MySQL复制表结构、表数据
    【Linux】vi(vim)起步学起来有些困难,一步一步温习
    【MySQL】MySQL PLSQL Demo
    【Linux】VMware中为CentOS设置静态IP(非动态获取IP)
  • 原文地址:https://www.cnblogs.com/BoscoGuo/p/5887649.html
Copyright © 2020-2023  润新知