zoukankan      html  css  js  c++  java
  • java多线程知识回顾(笔记)

    线程创建的方式 有两种

    第一种是继承Thread类 重写run方法 (个人偏向这一种实际中这种用的较多)

    例如

    public class MyThead extends  Thread {
    
        int j=20;
        public void run(){
            for (int i = 0; i < 20; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(this.getName()+",i="+j--);
            }
        }
    }
    

     这种自己测试时也很多人写

    new Thread(new Runnable() {
    @Override
    public void run() {

    }
    }).start(); 这样不好控制线程但是平时写一下也没关系

    第二种第二种是实现Runnable接口
    public class Thread3 implements  Runnable{
        @Override
        public void run() {
    
            for (int i = 0; i < 20; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("接口Runnable"+",i="+i--);
            }
    
        }
    
    }
    

      主线程调用方式

     public static void main(String[] args) throws InterruptedException {
    
    
            MyThead myThead= new MyThead();
            MyThread1 myThead1= new MyThread1();
            Thread3 thread3=new Thread3();
            //thread3.run();//这样不是开线程运行
            Thread t = new Thread(thread3);
            t.start();
            myThead.start();
            myThead1.start();
    
    
        }
    

      个人还是倾向继承Thead 赶脚方便

    -------------------------------------------------------------------------------------------------------------------

    线程实现后最多的也就是用到线程同步了(synchronized 关键字 其他锁以后说)

    来自

    https://www.cnblogs.com/blueSkyline/p/8598099.html
    自己大一学的时候感觉懵逼的不行 ...三年后清晰不少
    public class SynMethod {
        private static final Object staticLockObj = new Object();
        /**
         * 对象锁,代码级别,同一对象争用该锁,this为SynMethod实例,synchronized的锁绑定在this对象上
         */
        public void method1() {
            synchronized (this) {
                for (int i = 0; i < 100; i++) {
    
                    System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
                }
            }
        }
    
        /**
         * 对象锁,方法级别,同一对象争用该锁,普通(非静态)方法,synchronized的锁绑定在调用该方法的对象上,与上一个写法含义一致()
         */
        public synchronized void method2() {
            for (int i = 0; i < 500; i++) {
                System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
            }
        }
    
        /**
         * 对象锁,代码级别,同一类争用该锁,绑定在staticLockObj上,不同SynMethod实例,拥有同一个staticLockObj对象
         */
        public void method3() {
            synchronized (staticLockObj) {
                for (int i = 0; i < 50; i++) {
                    System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
                }
            }
        }
    
        /**
         * 类锁,代码级别,同一类争用该锁
         */
        public void method4() {
            synchronized (SynMethod.class) {
                for (int i = 0; i < 50; i++) {
                    System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
                }
            }
        }
    
        /**
         * 类锁,方法级别,同一类争用该锁,synchronized的锁绑定在SynMethod.class上
         */
        public static synchronized void staticMethod() {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);
            }
        }
    }
    

      解释的比较清楚 自己试一试才是关键 ........  

    为什么能加上去锁呢?对象头部都有一些标志位...详情百度

     ------------------------------------------------------------------------------------------

    大一的时候看过一个多线程简单的例子 火车站卖票的例子 一个线程相当于一个窗口 开多个窗口同时买票 且不重复

    但是看完之后有点懵逼 模棱两可也就过去了 现在明白不少 主要是上面的synchronized关键字 当然也可以用其他锁实现 先贴一下自己的例子

    public class Station extends Thread {
        public Station(String name) {
            super(name);// 给线程名字赋值
        }
       static int  tick=50;
    
        @Override
        public void run() {
            while (tick>0)
            {
                synchronized (Station.class)  //同步这里不能写this 可以是类 this 只会在本对象生效 new 一个新的没办法共同使用
                {
                    if (tick>0)
                    {
                        System.out.println(getName()+"卖了第"+tick+"张票");
                        tick--;
                    }else
                    {
                        System.out.println("票已经卖完");
                    }
    
                }
    
                try {
                    sleep(100);//这里让线程不得到CUP 一下否则可能一个线程把事情干完了 达不到模拟效果
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

      synchronized (Station.class) 可以使用注意不要用this 那样窗口买票可能会重复的...也可以 在station 类里面new 一个没用的object对象 用哪个对象当钥匙(因为你new 再多的对象还是用那一个object 看看synchronized 的前面的例子运行一下就明白很多) 这两种解决都可以 

    也可以station 类继承Runnable 接口 实现run方法 加锁的时候直接this  主方法new 一个对象  开启两个线程 也不会出问题

    买票main函数

     Station station1=new Station("窗口1");
            Station station2=new Station("窗口2");
            Station station3=new Station("窗口3");
            station1.start();
            station2.start();
            station3.start();
    View Code

    第二种写法 道理一样的 加锁那里写 this

    public class Station1 implements  Runnable{
        static int tick=1000;
        @Override
        public void run() {
    
                while (tick>0)
                {
    
                    synchronized (this)
                    {
                        System.out.println(Thread.currentThread().getName()+"卖出了第"+tick+"张飘");
                        tick--;
                        try {
                            Thread.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
    
    
                    }
    
            System.out.println("票已经卖完");
    
        }
    }
    

      main

     Station1 station11=new Station1();
            Thread t1=new Thread(station11,"第一个");
            Thread t2=new Thread(station11,"第二个");
            t1.start();
            t2.start();
  • 相关阅读:
    Azure PowerShell (7) 使用CSV文件批量设置Virtual Machine Endpoint
    Windows Azure Cloud Service (39) 如何将现有Web应用迁移到Azure PaaS平台
    Azure China (7) 使用WebMetrix将Web Site发布至Azure China
    Microsoft Azure News(4) Azure新D系列虚拟机上线
    Windows Azure Cloud Service (38) 微软IaaS与PaaS比较
    Windows Azure Cloud Service (37) 浅谈Cloud Service
    Azure PowerShell (6) 设置单个Virtual Machine Endpoint
    Azure PowerShell (5) 使用Azure PowerShell创建简单的Azure虚拟机和Linux虚拟机
    功能代码(1)---通过Jquery来处理复选框
    案例1.用Ajax实现用户名的校验
  • 原文地址:https://www.cnblogs.com/xuexidememeda/p/12245153.html
Copyright © 2011-2022 走看看