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() ;
	}
};
Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第1张图片
Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第2张图片
Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第3张图片

2、同步代码块

Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第4张图片
Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第5张图片
同步的时候,必须指明同步的对象,一般情况下会将当前对象作为同步对象,使用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() ;
	}
};
Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第6张图片

3、同步方法

Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第7张图片
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

Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第8张图片
Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第9张图片
线程操作经典案例程序:生产者和消费之问题,生产者不断生产,消费者不断取走生产者生产的产品。
加入等待与唤醒:
Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第10张图片
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、线程的生命周期

Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第11张图片
Java多线程--同步与死锁:synchronized;等待与唤醒:wait、notify、notifyAll;生命周期_第12张图片
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语法基础,Java基础学习篇)