线程相关

作者: z七夜 | 来源:发表于2018-05-26 20:52 被阅读5次

    1.线程创建

    • 继承Thread
    • 实现Runnable接口
    • 实现callable接口

    1.1继承Thread

     * 线程创建,
     *  继承Thread类,重写run方法
     */
    public class ThreadDemo1 extends Thread{
    
        private String name;
    
        public ThreadDemo1(String name){
            this.name = name;
        }
    
        @Override
        public void run() {
            System.out.println("hello "+name);
        }
    }
    

    说下静态代理:

    静态代理相关:
    什么是静态代理,

    对原有对象的不满意,想增强功能有三种方式

    • 继承:继承原有类,加上更多功能得到新的类,但是如果后来需要很多功能,会继承很多类,层级过高
    • 包装: 原理也是代理
    • 代理:新建一个代理类,实现原有接口,对对象进行增强

    静态代理:
    需要有原有对象,
    代理对象
    公共接口

    public class StaticProxy {
    
         public static void main(String[] args) {
             Man man = new Man("张三");
            // man.coding();
    
             ProxyMan proxyMan = new ProxyMan(man);
             proxyMan.coding();
         }
    
    }
    
    /**
     * 程序员接口,敲代码的方法
     */
    interface Programer{
        void coding();
    }
    
    class Man implements Programer{
        public String name;
    
        public String getName() {
            return name;
        }
    
        public Man(String name) {
            this.name = name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public void coding() {
            System.out.println(name+"正在辛苦的敲代码");
        }
    }
    
    class ProxyMan implements Programer{
    
        public Man man;
    
        public ProxyMan(Man man) {
            this.man = man;
        }
    
        @Override
        public void coding() {
            startComputer();
            System.out.println(man.getName()+"正在辛苦的敲代码");
            closeComputer();
        }
    
        private void closeComputer() {
            System.out.println(man.getName()+"关闭了电脑");
        }
    
        private void startComputer() {
            System.out.println(man.getName()+"开启电脑");
        }
    }
    

    1.2实现Runnable接口

    public class ThreadDemo2 {
    
         public static void main(String[] args) {
             Thread one = new Thread(new Demo2("线程1"));
             one.start();
             for (int j=0;j<100;j++){
                 System.out.println("zhangsan--"+j);
             }
         }
    }
    
    class Demo2 implements Runnable{
        public String name;
        public Demo2(String name) {
            this.name = name;
        }
    
        @Override
        public void run() {
            for (int i =0;i<100;i++){
                System.out.println(name+"--"+i);
            }
        }
    }
    

    Thread实现了Runnable接口,实际上是对线程的代理


    image.png

    1.3 实现Callable接口

    看我这篇

    2.线程状态

    它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)五种状态

    2.1 线程阻塞方法

    • join
    • sleep
    • yield

    Join方式(可用于多个线程顺序执行)

    public class JoinTreadDemo1 extends Thread{
    
        public static void main(String[] args) throws InterruptedException {
    
            JoinTreadDemo1 demo = new JoinTreadDemo1();
            demo.start();
    
            for (int j=0;j<100;j++){
                if (j==50){
                    demo.join();//main线程被阻塞,当demo这个线程结束之后才会执行main
                }
                System.out.println("main--"+j);
            }
         }
    
        @Override
        public void run() {
            for (int i=0;i<100;i++){
                System.out.println(Thread.currentThread().getName()+i);
            }
        }
    }
    

    yield方式,用于暂停自己

    public class YeildThreadDemo extends Thread{
         public static void main(String[] args) {
             YeildThreadDemo yeildThreadDemo = new YeildThreadDemo();
             yeildThreadDemo.start();
    
             for (int j=0;j<100;j++){
                 if (j==50){
                     Thread.yield();
                 }
                 System.out.println("main--"+j);
             }
         }
    
        @Override
        public void run() {
            for (int i=0;i<100;i++){
                System.out.println(Thread.currentThread().getName()+i);
            }
        }
    }
    

    sleep方式,常用于模拟网络延迟,或者倒计时

    3. 锁相关

    3.1 模拟12306买票

    10张票,由三个窗口售卖,如果不加锁,多线程情况下会出现假数据,卖相同的票

    public class Web12306 implements Runnable {
    
    
        private int num=50;//50张票
        @Override
        public void run() {
    
            while (true){
                if (num<0){
                    break;
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"售出了第"+num+"张票");
                num--;
            }
        }
         public static void main(String[] args) {
             Web12306 web12306 = new Web12306();
             //代理类
             Thread demo1 = new Thread(web12306, "黄牛1");
             Thread demo2 = new Thread(web12306, "黄牛2");
             Thread demo3 = new Thread(web12306, "黄牛3");
             demo1.start();
             demo2.start();
             demo3.start();
         }
    }
    

    加锁实现
    锁只能锁引用类型

    • 锁方法
    • 锁代码块
    • 锁字节码文件
    
    public class SynThreadDemo1 {
    
         public static void main(String[] args) {
    
             webtest web12306 = new webtest();
             //代理类
             Thread demo1 = new Thread(web12306, "黄牛1");
             Thread demo2 = new Thread(web12306, "黄牛2");
             Thread demo3 = new Thread(web12306, "黄牛3");
             demo1.start();
             demo2.start();
             demo3.start();
         }
    
    }
    
    class webtest implements Runnable{
        private int num=10;//50张票
    
        public boolean flag=true;
        @Override
        public void run() {
            while (flag){
               test3();
            }
        }
        public  void test3() {//锁代码块
            synchronized (this) {
                if (num <= 0) {
                    flag = false;
                    return;
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "售出了第" + num-- + "张票");
            }
        }
        public synchronized void test2() { //方法锁
            if (num<=0){
                flag = false;
                return;
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"售出了第"+num--+"张票");
    
        }
    
        public  void test1() { //不安全
            if (num<=0){
                flag = false;
                return;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"售出了第"+num+"张票");
            num--;
        }
    
    }
    

    3.2 单例模式的实现

    单例模式

    • 饿汉模式
    • 懒汉模式
      创建一个静态对象,调用静态方法,实现懒加载
    • 双重检查
    • 静态内部类
    
    public class MyJvm {
    
         public static void main(String[] args) {
             Jvm1 jvm1 = new Jvm1();
             Jvm1 jvm2 = new Jvm1();
    
             System.out.println(jvm1);
             System.out.println(jvm2);
    
         }
    
    }
    
    /**
     * 饿汉模式
     * 当类初始化时候就会创建实例
     */
    class Jvm1{
        private static Jvm1 jvm1 = new Jvm1();
    
        public static Jvm1 getInstance(){
            return jvm1;
        }
    
    }
    
    /**
     * 懒汉式,当调用方法时候才会初始化,懒加载
     */
    class Jvm2{
        private static Jvm2 jvm2 = null;
    
        public static Jvm2 getInstance(){
            if (jvm2 == null) {
                jvm2 = new Jvm2();
            }
            return jvm2;
        }
    
    }
    
    
    /**
     * 双重检查
     *
     */
    
    class Jvm3{
        private static Jvm3 jvm3 = null;
    
        public static Jvm3 getInstance(){
            if (jvm3 ==null){
                synchronized (Jvm3.class) {
                    if (jvm3 == null) {
                        jvm3 = new Jvm3();
                    }
                }
            }
            return jvm3;
        }
    
    }
    
    /**
     * 静态内部类
     */
    class Jvm4{
    
        private static class get{
            private static Jvm3 jvm3 = new Jvm3();
        }
    
        public static Jvm3 getInstance(){
            return get.jvm3;
        }
    
    }
    

    4.Timer

    定时器

    定时做什么任务
    倒计时案例

    public class TimerDemo {
    
         public static void main(String[] args) throws ParseException {
    
             String s ="02:00:00";
             SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
             Date parse = format.parse(s);
    
             Timer timer = new Timer();
             timer.schedule(new TimerTask() {
                 int i=1;
                 @Override
                 public void run() {
                     System.out.println("so easy..."+format.format(parse.getTime()-1000*i++));
                 }
             },1000,1000);
         }
    }
    
    

    更多交流 qq群:552113611
    码云源码:https://gitee.com/zhangqiye/Thread

    相关文章

      网友评论

        本文标题:线程相关

        本文链接:https://www.haomeiwen.com/subject/elqvjftx.html