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

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

  • 相关阅读:
    在Myeclipse中移除项目对Hibernate的支持
    使用MyEclipse可视化开发Hibernate实例
    利用MyEclipse自动创建PO类、hbm文件(映射文件)、DAO
    Mtk Camera
    Linux问题,磁盘分区打不开了
    Android SDK在线更新镜像服务器大全
    TeamTalk——ubuntu服务端部署
    Nginx
    VCC/AVCC/VDD/AVDD区别
    android studio and sdk mirror for China
  • 原文地址:https://www.cnblogs.com/niuxiao12---/p/7279163.html
Copyright © 2020-2023  润新知