线程的同步

1.临界资源问题:
1.1:临界资源:同一个进程中多个线程共享的资源,叫临界资源。

1.2:临界资源问题:当一个线程获得cpu时间片,运行共享资源,还没来得及修改共享资源 时,另一个线程将cpu时间片抢过去,运行还未来得有修改共享资源时就出 现问 题,叫临界资源问题。

2.线程同步:解决临界资源问题。将要一起执行的代码绑定在一块形成代码块,当一个线程抢到cpu 时间片,进入这个代码块执行时,其他的线程不能进行这个代码块中执行,直到当前的线 程执行完代码块,其他的线程抢到cpu时间片并且此时代码块中无线程执行,这个线程 才能进入代码块去执行。
2.1:同步代码块:
2.1.1:synchronized (同步锁) {
要绑定在一起执行的代码;
}
2.1.2:同步锁:只要是这多个线程共享的一个对象都可以作为同步锁对象,锁对象的值一般是不变。
2.1.3:锁的范围:锁的范围越小越好。

   eg:/**
 * 任务类
 * @author sx
 * @version 1.0 2019年7月16日
 */
public class MyRunnable2 implements Runnable{
	/**
	 * 票数的成员变量
	 */
	public int ticket=1000;
	
	/**
	 * 声明一个变量作为锁对象
	 */
	Object ob=new Object();
	
	/**
	 * 任务方法
	 */
	@Override
	public void run() {
		while (true) {
			//7,1,4
			//同步块
			synchronized (ob) {
				if (ticket>0) {
					System.out.println(Thread.currentThread().getName()+"正在销售第"+ticket+"张票");
					ticket--;
				}else {
					break;
				}
			}
		}
		System.out.println("票已售完");
		
	}
}

public static void main(String[] args) {
		//创建任务对象
		MyRunnable2 mr=new MyRunnable2();
		//创建10个线程对象售票,10个线程共享一个任务对象
		for (int i = 1; i <=10; i++) {
			if (i==10) {
				Thread t1=new Thread(mr);
				t1.setName("窗口0"+i);
				t1.start();
			}else {
				Thread t1=new Thread(mr);
				t1.setName("窗口00"+i);
				t1.start();
			}
		}
	}

2.2:同步方法:
2.2.1:同步方法的语法:
public synchronized 返回值类型 方法名(形参列表) {
要绑定在一起执行的代码;
}
2.2.2:同步方法的锁范围越小越好。

	eg:/**
 * 任务类
 * @author sx
 * @version 1.0 2019年7月16日
 */
public class MyRunnable2 implements Runnable{
	/**
	 * 票数的成员变量
	 */
	public int ticket=1000;
	
	/**
	 * 声明一个变量作为锁对象
	 */
	Object ob=new Object();
	
	/**
	 * 任务方法
	 */
	@Override
	public void run() {
		while (true) {
			if(saleTicket()==true) {
				break;
			}
		}
		System.out.println("票已售完");
		
	}
	
	/**
	 * 同步方法
	 */
	public synchronized boolean saleTicket() {
		if (ticket>0) {
			System.out.println(Thread.currentThread().getName()+"正在销售第"+ticket+"张票");
			ticket--;
			return false;
		}else {
			return true;
		}
	}
}

	public static void main(String[] args) {
		//创建任务对象
		MyRunnable2 mr=new MyRunnable2();
		//创建10个线程对象售票,10个线程共享一个任务对象
		for (int i = 1; i <=10; i++) {
			if (i==10) {
				Thread t1=new Thread(mr);
				t1.setName("窗口0"+i);
				t1.start();
			}else {
				Thread t1=new Thread(mr);
				t1.setName("窗口00"+i);
				t1.start();
			}
		}
	}

	2.3:对象互斥锁:
		2.3.1:对象互斥锁的语法:
				/**
	 * 声明一个锁对象
	 */
  Lock l=new ReentrantLock();
	
			//上锁
		  l.lock();
		要绑定在一起执行的代码
   //解锁
  l.unlock();

2.3.2:锁的范围越小越好。
2.3.3:对象互斥锁要确保在任何情况下解锁,防止出现死锁。

eg:public class MyRunnable2 implements Runnable{
	/**
	 * 票数的成员变量
	 */
	public int ticket=1000;

/**
 * 声明一个对象互斥锁对象
 */
Lock l=new ReentrantLock();

/**
 * 任务方法
 */
@Override
public void run() {
	while (true) {
		try {
			//上锁
			l.lock();
			if (ticket>0) {//9
				System.out.println(Thread.currentThread().getName()+"正在销售第"+ticket+"张票");
				ticket--;
			}else {
				break;
			}
		} finally {
			//解锁
			l.unlock();
		}
	}
	System.out.println("票已售完");
}

}

3.线程同步的作用:解决临界资源问题
优点:安全性高。同步的代码块中每次只允许一个线程进去执行,只有等待这个线程执行完 了,其他的线程才有机会进行执行。
缺点:效率低。一个线程要抢到cpu时间片,并且同步代码块中没有线程在执行,才能进入同步 块中去执行。

4.线程池的作用:减少创建线程和关闭线程的时间和系统资源的消耗。

5.线程池:存放多个线程对象的容器。

6.线程池中重要的接口和类

6.1:ExecutorService:线程池的接口

6.2:Executors:创建各种线程池的工具类

6.3:newSingleThreadExecutor():创建一个单线程的线程池。这个线程池只有一个线程在工 作,也就是相当于单线程串行执行所有任务。如果这个唯一的线 程因 为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序 按照任务的提交顺序执行。

6.4:newFixedThreadPool(int n)
创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池 的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行 异常而结束,那么线程池会补充一个新线程。

6.5:newCachedThreadPool()
创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那 么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又 可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池 大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

eg:public static void main(String[] args) {
		//创建线程池对象
		//ExecutorService pool1=Executors.newSingleThreadExecutor();
		//ExecutorService pool1=Executors.newFixedThreadPool(2);
		ExecutorService pool1=Executors.newCachedThreadPool();
	
	//创建任务对象
	MyRunnable mr1=new MyRunnable();
	MyRunnable mr2=new MyRunnable();
	MyRunnable mr3=new MyRunnable();
	
	//从线程池中取出线程对象执行任务
	pool1.submit(mr1);
	pool1.submit(mr2);
	pool1.submit(mr3);
	
	//关闭线程池
	pool1.shutdown();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值