java学习第二十三次笔记—— ——线程后续

系列文章目录

一、线程同步

1.同步代码块(卖票)

(1)第一种方式

package demo01;

public class Demo05Ticket {
    
    
	public static void main(String[] args) {
    
    
		RunnableImpl run= new RunnableImpl();
		Thread t0= new Thread(run);
		Thread t1= new Thread(run);
		Thread t2= new Thread(run);
		
		t0.start();
		t1.start();
		t2.start();
	}

}

package demo01;
/*
 * 
 * 
 * 解决线程安全问题的一种方案:使用同步代码块
 * 格式:
 * 		synchronized(锁对象){
 * 				可能会出现线程安全的代码(是因为访问了共享的数据)
 * }
 * 注意:
 * 1、通过代码块中的锁对象,可以使用任意的对象
 * 2、但是必须保证多个线程使用的锁对象是统一个
 * 3、锁对象作用:
 * 		把同步代码块锁住,只让一个线程执行
 * 
 * 
 */
public class RunnableImpl implements Runnable {
    
    
	private int ticket =100;
	//Object obj=new Object();
	@Override
	public void run() {
    
    
		while(true) {
    
    
			payTicket();
		}
	}
	public synchronized void payTicket() {
    
    
		if(ticket>0) {
    
    
			try {
    
    
				Thread.sleep(10);
			}catch (InterruptedException e) {
    
    
				e.printStackTrace();
			}
			
				System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");
				ticket--;
			}
		}

	}


	
	



(2)第二种方式

package demo02;



public class demo01Ticket {
    
    
	public static void main(String[] args) {
    
    
		Runnablempl run= new Runnablempl();
		Thread t0= new Thread(run);
		Thread t1= new Thread(run);
		Thread t2= new Thread(run);
		
		t0.start();
		t1.start();
		t2.start();
	}

}

package demo02;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/*
 * 
 * 解决线程安全的第二种方法:使用同步方法
 * 	使用步骤:
 * 		1、把访问了共享数据的代码块抽取出来,放到一个方法中
 * 		2、在方法上添加synchronized修饰符
 * 
 */
public class Runnablempl implements Runnable{
    
    
	private int ticket=100;
	//1.在成员位置创建一个Reentrantlock对象
	Lock l=new ReentrantLock();
	@Override
	public void run() {
    
    
		
		while(true) {
    
    
			//2.在可能会出现线程安全的地方,调用lock接口中的lock方法,获取锁
			
			l.lock();
			if(ticket>0) {
    
    
				
				try {
    
    
					Thread.sleep(10);
					System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");
					ticket--;
				}catch (InterruptedException e) {
    
    
					e.printStackTrace();
				
				}finally {
    
    
					l.unlock();
				}
			//3.在可能出现线程安全问题的代码调用过后,使用unlock释放锁
		}
	}
	}
}

			
		

二、生产者消费者

1.生产者消费者模式概述

在这里插入图片描述

在这里插入图片描述

代码如下(示例):

package demo03;
/*
 * 等待唤醒案例:
 * 		创建一个顾客线程:告知老板要的包子的种类,用wait()方法等待,放弃cpu执行,
 * 		创建一个老板线程:花五秒做一个包子,做好过后,用notif通知顾客吃包子
 * 
 * 
 * 
 * 
 * 
 */
public class demo03WatiAndNotify {
    
    
	public static void main(String[] args) {
    
    
		Object obj= new Object();
		//创建第一个消费者
		new Thread() {
    
    
			public void run() {
    
    
				while(true) {
    
    
					synchronized(obj) {
    
    
						System.out.println("消费:1:告知老板要的包子的种类");
						
						try {
    
    
							obj.wait();
						}catch (InterruptedException e) {
    
    
							e.printStackTrace();
						}
						System.out.println("消费者2:包子已经做好了,开吃");
						System.out.println("======================");
					}
				}
			}
		}.start();
		
		new Thread() {
    
    
			public void run() {
    
    
				while(true) {
    
    
					try {
    
    
						Thread.sleep(2000);
					}catch(InterruptedException e) {
    
    
						e.printStackTrace();
					}
					synchronized (obj) {
    
    
						System.out.println("生产者:老板花2秒做好了一个包子,告知顾客吃包子");
						obj.notify();
					}
				}
			}
		}.start();
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_54405545/article/details/117334478