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();
  • 相关阅读:
    dede织梦编辑器中插入视频文件方法
    织梦在PHP7上安装模块时模块包含的文件为空的解决方法
    织梦dedecms整合添加ckplayer播放器支持flv,mp4等播放功能
    实现dedecms全站动态浏览
    【idea快捷键】
    【Android-stdio-appdemo搭建记录】
    【随记-插件-】
    【mysql远程连库】
    【策略模式和工厂模式的比较】
    【极客学院-idea教程】
  • 原文地址:https://www.cnblogs.com/xuexidememeda/p/12245153.html
Copyright © 2011-2022 走看看