zoukankan      html  css  js  c++  java
  • Java多线程---------同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期

    1、问题的引出


    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() ;
    	}
    };

    2、同步代码块



    同步的时候,必须指明同步的对象,一般情况下会将当前对象作为同步对象,使用this表示。
    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() ;
    	}
    };

    3、同步方法


    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() ;
    	}
    };

    4、死锁

    过多的同步可能导致死锁:死锁表示在程序时,互相等待。

    程序模拟:张三向李四要画,用书交换;李四向张三要书,用画交换。

    class Zhangsan{	// 定义张三类
    	public void say(){
    		System.out.println("张三对李四说:“你给我画,我就把书给你。”") ;
    	}
    	public void get(){
    		System.out.println("张三得到画了。") ;
    	}
    };
    class Lisi{	// 定义李四类
    	public void say(){
    		System.out.println("李四对张三说:“你给我书,我就把画给你”") ;
    	}
    	public void get(){
    		System.out.println("李四得到书了。") ;
    	}
    };
    public class ThreadDeadLock implements Runnable{
    	private static Zhangsan zs = new Zhangsan() ;		// 实例化static型对象
    	private static Lisi ls = new Lisi() ;		// 实例化static型对象
    	private boolean flag = false ;	// 声明标志位,判断那个先说话
    	public void run(){	// 覆写run()方法
    		if(flag){
    			synchronized(zs){	// 同步张三
    				zs.say() ;
    				try{
    					Thread.sleep(500) ;
    				}catch(InterruptedException e){
    					e.printStackTrace() ;
    				}
    				synchronized(ls){
    					zs.get() ;
    				}
    			}
    		}else{
    			synchronized(ls){
    				ls.say() ;
    				try{
    					Thread.sleep(500) ;
    				}catch(InterruptedException e){
    					e.printStackTrace() ;
    				}
    				synchronized(zs){
    					ls.get() ;
    				}
    			}
    		}
    	}
    	public static void main(String args[]){
    		ThreadDeadLock t1 = new ThreadDeadLock() ;		// 控制张三
    		ThreadDeadLock t2 = new ThreadDeadLock() ;		// 控制李四
    		t1.flag = true ;
    		t2.flag = false ;
    		Thread thA = new Thread(t1) ;
    		Thread thB = new Thread(t2) ;
    		thA.start() ;
    		thB.start() ;
    	}
    };

    5、Object类对线程的支持-----------唤醒和等待:notify、notifyAll、wait



    线程操作经典案例程序:生产者和消费之问题,生产者不断生产,消费者不断取走生产者生产的产品。
    加入等待与唤醒:

    class Info{	// 定义信息类
    	private String name = "李兴华";	 // 定义name属性
    	private String content = "JAVA讲师"  ;		// 定义content属性
    	private boolean flag = false ;	// 设置标志位
    	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(){
    		if(flag){
    			try{
    				super.wait() ;
    			}catch(InterruptedException e){
    				e.printStackTrace() ;
    			}
    		}
    		try{
    			Thread.sleep(300) ;
    		}catch(InterruptedException e){
    			e.printStackTrace() ;
    		}
    		System.out.println(this.getName() + 
    			" --> " + this.getContent()) ;
    		flag  = true ;	// 改变标志位,表示可以生产
    		super.notify() ;
    	}
    	public void setName(String name){
    		this.name = name ;
    	}
    	public void setContent(String content){
    		this.content = content ;
    	}
    	public String getName(){
    		return this.name ;
    	}
    	public String getContent(){
    		return this.content ;
    	}
    };
    class Producer implements Runnable{	// 通过Runnable实现多线程
    	private Info info = null ;		// 保存Info引用
    	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.mldnjava.cn") ;	// 设置名称
    				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++){
    			this.info.get() ;
    		}
    	}
    };
    public class ThreadCaseDemo03{
    	public static void main(String args[]){
    		Info info = new Info();	// 实例化Info对象
    		Producer pro = new Producer(info) ;	// 生产者
    		Consumer con = new Consumer(info) ;	// 消费者
    		new Thread(pro).start() ;
    		new Thread(con).start() ;
    	}
    };

    6、线程的生命周期



    class MyThread implements Runnable{
    	private boolean flag = true ;	// 定义标志位
    	public void run(){
    		int i = 0 ;
    		while(this.flag){
    			System.out.println(Thread.currentThread().getName()
    				+"运行,i = " + (i++)) ;
    		}
    	}
    	public void stop(){
    		this.flag = false ;	// 修改标志位
    	}
    };
    public class StopDemo{
    	public static void main(String args[]){
    		MyThread my = new MyThread() ;
    		Thread t = new Thread(my,"线程") ;	// 建立线程对象
    		t.start() ;	// 启动线程
    		try{
    			Thread.sleep(30) ;
    		}catch(Exception e){
    			
    		}
    		my.stop() ;	// 修改标志位,停止运行
    	}
    };





  • 相关阅读:
    java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory
    项目开发中关于权限的实现方案简单描述(帮助以后回忆)
    一些比较有用的模板
    递归之遍历部门
    关于s2sh框架关于hibernate懒加载问题的说明和解决方案
    Hibernate实体映射配置(XML)简单三步完美配置
    项目添加性能监控日志
    redis常用命令大全
    redis主从同步
    redis之哨兵部署运行日志解读
  • 原文地址:https://www.cnblogs.com/pangblog/p/3365999.html
Copyright © 2011-2022 走看看