zoukankan      html  css  js  c++  java
  • 多线程(一)

    synchronized关键字实现多线程的3种方式:


    1. 继承Thread类
    2. 实现Runnable接口
    3. 匿名类的方式

    注: 启动线程是start()方法,run()并不能启动一个新的线程

    一.继承线程类

    使用多线程,就可以做到盖伦在攻击提莫的同时,赏金猎人也在攻击盲僧 
    设计一个类KillThread 继承Thread,并且重写run方法 
    启动线程办法: 实例化一个KillThread对象,并且调用其start方法 
    就可以观察到 赏金猎人攻击盲僧的同时,盖伦也在攻击提莫

    package multiplethread;
     
    import charactor.Hero;
     
    public class KillThread extends Thread{
         
        private Hero h1;
        private Hero h2;
     
        public KillThread(Hero h1, Hero h2){
            this.h1 = h1;
            this.h2 = h2;
        }
     
        public void run(){
            while(!h2.isDead()){
                h1.attackHero(h2);
            }
        }
    }
    KillThread.java
    package multiplethread;
     
    import charactor.Hero;
     
    public class TestThread {
     
        public static void main(String[] args) {
             
            Hero gareen = new Hero();
            gareen.name = "盖伦";
            gareen.hp = 616;
            gareen.damage = 50;
     
            Hero teemo = new Hero();
            teemo.name = "提莫";
            teemo.hp = 300;
            teemo.damage = 30;
             
            Hero bh = new Hero();
            bh.name = "赏金猎人";
            bh.hp = 500;
            bh.damage = 65;
             
            Hero leesin = new Hero();
            leesin.name = "盲僧";
            leesin.hp = 455;
            leesin.damage = 80;
             
            KillThread killThread1 = new KillThread(gareen,teemo);
            killThread1.start();
            KillThread killThread2 = new KillThread(bh,leesin);
            killThread2.start();
             
        }
         
    }
    TestThread

    二.实现Runnable接口

    创建类Battle,实现Runnable接口
    启动的时候,首先创建一个Battle对象,然后再根据该battle对象创建一个线程对象,并启动

    package multiplethread;
     
    import charactor.Hero;
     
    public class Battle implements Runnable{
         
        private Hero h1;
        private Hero h2;
     
        public Battle(Hero h1, Hero h2){
            this.h1 = h1;
            this.h2 = h2;
        }
     
        public void run(){
            while(!h2.isDead()){
                h1.attackHero(h2);
            }
        }
    }
    Battle.java
    package multiplethread;
     
    import charactor.Hero;
     
    public class TestThread {
     
        public static void main(String[] args) {
             
            Hero gareen = new Hero();
            gareen.name = "盖伦";
            gareen.hp = 616;
            gareen.damage = 50;
     
            Hero teemo = new Hero();
            teemo.name = "提莫";
            teemo.hp = 300;
            teemo.damage = 30;
             
            Hero bh = new Hero();
            bh.name = "赏金猎人";
            bh.hp = 500;
            bh.damage = 65;
             
            Hero leesin = new Hero();
            leesin.name = "盲僧";
            leesin.hp = 455;
            leesin.damage = 80;
             
            Battle battle1 = new Battle(gareen,teemo);
             
            new Thread(battle1).start();
     
            Battle battle2 = new Battle(bh,leesin);
            new Thread(battle2).start();
     
        }
         
    }
    TestThread

    三.匿名类

    使用匿名类,继承Thread,重写run方法,直接在run方法中写业务代码
    匿名类的一个好处是可以很方便的访问外部的局部变量。
    前提是外部的局部变量需要被声明为final。(JDK7以后就不需要了)
     
    package multiplethread;
      
    import charactor.Hero;
      
    public class TestThread {
      
        public static void main(String[] args) {
              
            Hero gareen = new Hero();
            gareen.name = "盖伦";
            gareen.hp = 616;
            gareen.damage = 50;
      
            Hero teemo = new Hero();
            teemo.name = "提莫";
            teemo.hp = 300;
            teemo.damage = 30;
              
            Hero bh = new Hero();
            bh.name = "赏金猎人";
            bh.hp = 500;
            bh.damage = 65;
              
            Hero leesin = new Hero();
            leesin.name = "盲僧";
            leesin.hp = 455;
            leesin.damage = 80;
              
            //匿名类
            Thread t1= new Thread(){
                public void run(){
                    //匿名类中用到外部的局部变量teemo,必须把teemo声明为final
                    //但是在JDK7以后,就不是必须加final的了
                    while(!teemo.isDead()){
                        gareen.attackHero(teemo);
                    }              
                }
            };
             
            t1.start();
              
            Thread t2= new Thread(){
                public void run(){
                    while(!leesin.isDead()){
                        bh.attackHero(leesin);
                    }              
                }
            };
            t2.start();
             
        }
          
    }
    TestThread.java

    四.常见线程方法:链接

    五.Concurrency 问题(并发性):链接

     

    package multiplethread;
      
    import java.text.SimpleDateFormat;
    import java.util.Date;
       
    public class TestThread {
         
        public static String now(){
            return new SimpleDateFormat("HH:mm:ss").format(new Date());
        }
         
        public static void main(String[] args) {
            final Object someObject = new Object();
              
            Thread t1 = new Thread(){
                public void run(){
                    try {
                        System.out.println( now()+" t1 线程已经运行");
                        System.out.println( now()+this.getName()+ " 试图占有对象:someObject");
                        synchronized (someObject) {
                              
                            System.out.println( now()+this.getName()+ " 占有对象:someObject");
                            Thread.sleep(5000);
                            System.out.println( now()+this.getName()+ " 释放对象:someObject");
                        }
                        System.out.println(now()+" t1 线程结束");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            };
            t1.setName(" t1");
            t1.start();
            Thread t2 = new Thread(){
      
                public void run(){
                    try {
                        System.out.println( now()+" t2 线程已经运行");
                        System.out.println( now()+this.getName()+ " 试图占有对象:someObject");
                        synchronized (someObject) {
                            System.out.println( now()+this.getName()+ " 占有对象:someObject");
                            Thread.sleep(5000);
                            System.out.println( now()+this.getName()+ " 释放对象:someObject");
                        }
                        System.out.println(now()+" t2 线程结束");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            };
            t2.setName(" t2");
            t2.start();
        }
           
    }
    TestThread.java
    17:00:34 t2 线程已经运行
    17:00:34 t1 线程已经运行
    17:00:34 t2 试图占有对象:someObject
    17:00:34 t1 试图占有对象:someObject
    17:00:34 t2 占有对象:someObject
    17:00:39 t2 释放对象:someObject
    17:00:39 t2 线程结束
    17:00:39 t1 占有对象:someObject
    17:00:44 t1 释放对象:someObject
    17:00:44 t1 线程结束
    

    在recover前,直接加上synchronized ,其所对应的同步对象,就是this
    和hurt方法达到的效果是一样
    外部线程访问gareen的方法,就不需要额外使用synchronized 了

    //回血
        //直接在方法前加上修饰符synchronized
        //其所对应的同步对象,就是this
        //和hurt方法达到的效果一样
        public synchronized void recover(){
            hp=hp+1;
        }
         
        //掉血
        public void hurt(){
            //使用this作为同步对象
            synchronized (this) {
                hp=hp-1;   
            }
        }
  • 相关阅读:
    POJ 1265 Pcik定理
    POJ 1380 坐标旋转
    POJ 1788
    POJ 3714 平面最近点对
    POJ 1905 二分
    POJ 1151 矩形面积并
    POJ 1654 多边形面积
    ZOJ 1010 判断简单多边形+求面积
    about work
    Python 打印 不换行
  • 原文地址:https://www.cnblogs.com/exciting/p/10705661.html
Copyright © 2011-2022 走看看