• 并发编程


    串行和并行:
      串行:一个线程在处理操作
      并行:多个线程在处理同一个操作
    什么叫做并发编程:在多线程环境下,应用程序的执行
    并发编程的目的:充分运用到资源,提高程序的效率

    什么情况下用到并发编程:
      1.在线程阻塞时,导致应用程序停止
      2.处理任务时间过长时,可以创建子任务,来进行分段处理
      3.间断任务执行


    一.并发编程中待解决的问题
      1.并发编程中频繁上下文切换的问题
        频繁上下文切换,可能会带来一定的性能开销
        如何减少上下文性能开销:
          1.无锁并发编程
          2.CAS
          3.使用最少线程数量
          4.协程:在单线程环境下进行多任务的调度,可以在多任务之间进行任务切换


      2.并发编程中死锁问题
          多个线程在抢占资源,但是抢占过程当中资源如果被占用,会造成阻塞,如果多个线程互抢资源时,就会造成死锁情况,死锁会导致应用程序的阻塞

      案例: 

      

    public class DeadLockDemo {
    	//资源
    	private static final Object HAIR_A=new Object();
    	private static final Object HAIR_B=new Object();
    
    	public static void main(String[] args) {
    		//第一个人
    		new Thread(()->{
    			//护住自己的头发
    			synchronized (HAIR_A){
    				System.out.println("第一个人护住自己的头发,准备薅第二个人的头发");
    				//延迟时间
    				try {
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				//薅第二个人的头发
    				synchronized (HAIR_B){
    					System.out.println("第一个人薅到了第二个人的头发");
    				}
    			}
    		}).start();
    		//第二个人
    		new Thread(()->{
    			//护住自己的头发
    			synchronized (HAIR_B){
    				System.out.println("第二个人护住自己的头发,准备薅第一个人的头发");
    				//延迟时间
    				try {
    					Thread.sleep(100);      //当前线程休眠,让渡CPU资源
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				//薅第一个人的头发
    				synchronized (HAIR_A){
    					System.out.println("第二个人薅到了第一个人的头发");
    				}
    			}
    		}).start();
    	}
    }
    

      

        如何预防死锁问题:
          1.破坏请求和保持条件:在申请资源时,一次性将资源都申请到
          2.破坏不可占用条件:抢占资源如何不满足,那就释放所有资源,以后如果再需要则再次申请即可
          3.破坏循环等待条件

      3.线程安全问题
        多个线程同时操作同一个资源,可能会造成资源数据不安全问题

        示例:

          

    public class UnsafeThread {
    	//资源
    	private static int num=0;
    		//计算线程数量
    		private static CountDownLatch countDownLatch=new CountDownLatch(10);
    		//对资源进行操作
    		public static void inCreate(){
    			num++;
    		}
    
    
    		public static void main(String[] args) throws InterruptedException {
    			for (int i = 0 ; i < 10 ; i++ ){
    				new Thread(()->{
    					for (int j = 0 ; j < 100; j++){
    						inCreate();
    						try {
    							Thread.sleep(100);
    						} catch (InterruptedException e) {
    							e.printStackTrace();
    						}
    					}
    					//每一个线程执行完毕,让计数-1
    					countDownLatch.countDown();
    				}).start();
    			}
    			//等待计数器为0或者小于0执行await下面代码
    			countDownLatch.await();
    			System.out.println(num);
    		}
    	}
    }
    

      解决线程不安全问题:

    public class UnsafeThread {
    	//资源
    	private static int num=0;
    	//计算线程数量
    	private static CountDownLatch countDownLatch=new CountDownLatch(10);
    	private static ReentrantLock reentrantLock = new ReentrantLock();
    
    	//对资源进行操作
    	public static  void inCreate(){
    
    		//上锁
    		reentrantLock.lock();
    		num++;
    		reentrantLock.unlock();
    	}
    	
    	public static synchronized void inCreate(){
    		//上锁		
    		num++;		
    	}
    	
    	public static synchronized void inCreate(){
    		//上锁
    		synchronized(UnsafeThread.class){
    			num++;
    		}
    	}
    
    
    	public static void main(String[] args) throws InterruptedException {
    		for (int i = 0 ; i < 10 ; i++ ){
    			new Thread(()->{
    				for (int j = 0 ; j < 100; j++){
    					inCreate();
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    				//每一个线程执行完毕,让计数-1
    				countDownLatch.countDown();
    			}).start();
    
    		}
    		//等待计数器为0或者小于0执行await下面代码
    		countDownLatch.await();
    		//获取到当前计数器中的线程数量
    		/*while (true){
    			if(countDownLatch.getCount()<=5){
    				System.out.println(num);
    				break;
    			}
    		}*/
    		System.out.println(num);
    
    
    	}
    }
    

      

  • 相关阅读:
    MySQL多实例,主从同步
    MySQL+Sphinx实现全文搜索
    Es+kafka搭建日志存储查询系统(设计)
    CSS中的rem
    JavaScript 中变量、作用域和内存问题的学习
    LVS使用整理(1)
    【Spark】---- Spark 硬件配置
    javascript的正则表达式总结
    javascript中的contains方法和compareDocumentPosition方法
    JavaScript DOM的一些扩展
  • 原文地址:https://www.cnblogs.com/F017/p/12517356.html
Copyright © 2020-2023  润新知