synchronized 线程同步 和 线程池

// synchronized ['sɪŋkrənaɪzd] 同步的
// 可以保证块中的代码是同步执行的
// 只有一个线程执行完块中的代码后,另外一个线程才能执行块中的代码
// 可以称为同步锁

	@Override
	public void run() {

		// synchronized ['sɪŋkrənaɪzd] 同步的
		// 可以保证块中的代码是同步执行的
		// 只有一个线程执行完块中的代码后,另外一个线程才能执行块中的代码
		// 可以称为同步锁

		while (true) {

			synchronized (this) { // 加锁,只有当前线程才可以使用

				if (ticket > 0) {

					System.out.println("TaskRunable 卖了一张票....");

					ticket--;

				} else {
					
					break;
				}

			}// 解锁

		} 

	}

  

	@Override
	public void run() {

		while (true) {
			// 返回值决定是否跳出循环
			boolean flag = sellTicket();
			
			if (flag) {
				
				break;
			}
		}
	}

	// synchronized 修饰的方法为同步方法,多线程间依次执行
	private synchronized boolean sellTicket() {
		
		boolean result = false;
		
		if (ticket > 0) {

			try {
				
				// 让当前线程休眠一段时间,暂停一段时间,线程进入阻塞状态
				// 唤醒线程进入就绪状态
				// 单位是毫秒
				Thread.sleep(500);
			} catch (InterruptedException e) {
				
				// 打断休眠会产生异常
				e.printStackTrace();
			}
			
			// Thread.currentThread() 获得当前代码在哪个线程执行
			// getName() 获得当前线程的名字
			System.out.println(Thread.currentThread().getName() + " 卖了一张票,剩余:" + (--ticket) + " 张");
		}else {
			
			result = true;
		}
		
		return result;
	}

  2  线程池的使用

// 使用线程池可以避免创建大量的线程,实现线程的重用,提高效率
// ExecutorService 线程池
// Executors 线程池创建对象
// newCachedThreadPool:容量无限的线程池
// 有可重用的就重用,没有就创建新的线程

ExecutorService executorService1 = Executors.newCachedThreadPool();
		
		for (int i = 0; i < 30; i++) {
			
			if (i % 5 == 0) {
				
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			TaskThread taskThread = new TaskThread();
			
			// 把需要再分线程执行的任务加入线程中
			executorService1.execute(taskThread);
		}
		
		// 线程池使用完要关闭,清理所有资源。
		executorService1.shutdown();

  

// newFixedThreadPool:指定容量的线程池
// 有可重用的就重用,没有就等待别人使用完毕再使用

ExecutorService executorService2 = Executors.newFixedThreadPool(10);
		
		for (int i = 0; i < 30; i++) {
			
			TaskThread taskThread = new TaskThread();
			
			executorService2.execute(taskThread);
		}
		
		executorService2.shutdown();

  

// newSingleThreadExecutor:容量为 1 的线程池
// 排队使用

ExecutorService executorService3 = Executors.newSingleThreadExecutor();
		
		for (int i = 0; i < 30; i++) {
			
			TaskThread taskThread = new TaskThread();
			
			executorService3.execute(taskThread);
		}
		
		executorService3.shutdown();

 // 实际工作中,对于大量的并发操作都会使用线程池进行管理,节省资源,提高效率 通过以上得出三种创建线程和使用的方法基本一样   可以根据实际情况来使用

原文地址:https://www.cnblogs.com/niuxiao12---/p/7279163.html