• java多线程


     java 多线程是在java中常用到的技术, 下面先从一个最简单的线程创建开始讲起。

     

    多线程 的好处:
    1. 解决一个进程中可以同时执行多个任务的问题。
    2. 提高了资源利用率。

    多线程的弊端:
    1. 增加了cpu的负担。
    2. 降低了一个进程中线程 的执行概率。
    3. 出现了线程 安全问题。
    4. 会引发死锁现象。

    自定义线程 的实现方式:

    方式一 :
    1. 自定义一个类继承Thread类。
    2. 重写Thread类的run方法,把自定义线程的任务代码写在run方法上。
    3. 创建Thread的子类对象,并且调用start方法启动一个线程。

    注意:千万不要直接调用run方法,调用start方法的时候线程就会开启,线程一旦开启就会执行run方法中代码,如果直接调用run方法,那么就 相当于调用了一个普通的方法而已。

    //创建一个类让这个类继承Thread类,这个类就是个线程类了。
    public class Demo1 extends Thread {
    
        //重写此类的构造函数,给这个线程起一个名称
        public  Demo1(String name){
            
            super(name);
            
        }
        
        //重写父类的run方法
        public  void run() {
            
            //输出从1到100
            for(int i=0;i<100;i++){
            
                System.out.println(this.getName()+i);
            }
        }
        
        public static void main(String[] args) throws Exception{
            
            //实例化线程
            Demo1 dome=new  Demo1("徐周");
            
            //给当前线程定一个暂定时间,暂定时间结束后线程继续执行
            dome.sleep(1000);
             
            //起动线程,从start()开始线程才开始真正等待CPU动行
            dome.start();
             
            //输出当前线程的优先级别java线程一共10个级别1-10
            System.out.println(dome.getPriority());
             
            //输出主线程的优先级别
             System.out.println(Thread.currentThread().getPriority());
              
             for (int i = 0; i < 100; i++) {
                
                 System.out.println("dddd主线程");
            }
            
            
        }
    
    }

     

    一个最简单的java多线程就写完了,下面我们再来看线程安全问题。

    package com.xuzhou;
    
     
    public class xuzhou2 extends Thread {
    
         static int sum=50;
         
         static Object o=new Object();
        
        public xuzhou2(String name){
            
            super(name);
        }
        @Override
        public void run() {
            
            while(true){
                                
                    if(sum>0){
                                            System.out.println(Thread.currentThread().getName()+"出售了第"+sum+"张票");
                        
                        sum--;
                    }else{
                        
                        
                        System.out.println("票已经卖完了");
                        
                        break;
                    }
                
                
            }
            
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            
            xuzhou2 mode1=new  xuzhou2("窗口1");
            xuzhou2 mode2=new  xuzhou2("窗口2");
            xuzhou2 mode3=new  xuzhou2("窗口3");
    
             mode1.start();
             mode2.start();
             mode3.start();
             
            
             
        }
    
    }

      

    运行这段代码,我们会发现一个问题,就是同一个数据会出现2次,为什么这样呢?我们已经定义了 static int sum=50 为静态成员了,但运行的时候还是会出现sum相同的数据,这次是线程安全问题,因为CPU会抢资源,3个线程都在操作一个run方法,
    当一个线程刚刚输出System.out.println(Thread.currentThread().getName()+"出售了第"+sum+"张票");的时候还没来得急Sum--,这个时候CPU有可能就会抢资源,第二个线程这个时候进来了,所以就会造成输出相同的数,出现线程安全问题。

      程安全出现 的根本原因:
      1. 存在两个或者两个以上 的线程对象共享同一个资源。
      2. 多线程操作共享资源的代码 有多句。

    这个问题怎么解决呢,其实很好解决在run方法里面加一个synchronized ("锁")就行,如下:
    package com.xuzhou;
    
     
    public class xuzhou2 extends Thread {
    
         static int sum=50;
         
         static Object o=new Object();
        
        public xuzhou2(String name){
            
            super(name);
        }
        @Override
        public void run() {
            
            while(true){
                synchronized ("锁") {
                    
                    if(sum>0){
                        
                        System.out.println(Thread.currentThread().getName()+"出售了第"+sum+"张票");
                        
                        sum--;
                    }else{
                        
                        
                        System.out.println("票已经卖完了");
                        
                        break;
                    }
                }
                
            }
            
        }
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            
            xuzhou2 mode1=new  xuzhou2("窗口1");
            xuzhou2 mode2=new  xuzhou2("窗口2");
            xuzhou2 mode3=new  xuzhou2("窗口3");
    
             mode1.start();
             mode2.start();
             mode3.start();
             
            
             
        }
    
    }

      运行这段代码,就不会再出现线程安全的问题了,为什么加上synchronized (锁对象)就不会出现线程安全问题呢?

    java中每个对象都有一个锁,默认对象是没有加锁的,当我们加上synchronized (锁对象)时,这个对象就会锁住了,当这个对象被锁住时,别的进程就无法访问些对象了,只有当前进程出了这个ynchronized (锁对象)时 ,对象会再次打开,别的进程才能进来,这样就不会出现 线程安全问题了。

      同步函数synchronized要注意的事项 :
      1. 如果是一个非静态的同步函数的锁 对象是this对象,如果是静态的同步函数的锁 对象是当前函数所属的类的字节码文件(class对象)。
      2. 同步函数的锁对象是固定的,不能由你来指定 的。

     
    
    
     

     

    先写到这,有时间一点一点完善。

  • 相关阅读:
    web网页端上传用户头像,后端获取后,返回路径给前端做展示
    获取时间戳后按要求转换为要使用的条件
    本地测试环境获取微信授权的,不用在手动跳过
    php批量压缩指定目录的图片,优点-比工具快好多陪。
    git 生成本地密钥
    商品活动抽奖概率算法
    thinkadmin-controller下面的api接口访问形式
    SpringMVC的请求和响应
    SpringMVC注解解析和项目配置
    SpringMVC 概述
  • 原文地址:https://www.cnblogs.com/xu3593/p/5716396.html
Copyright © 2020-2023  润新知