线程相关

作者: 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

相关文章

  • android linux pThread使用

    线程的相关方法 方法前缀相关功能pthread_线程本身和各种相关函数pthread_attr_线程属性对象pth...

  • iOS面试进阶篇(二)

    目录 UITableViewCell相关试题多线程相关试题进程与线程相关试题网络相关试题TCP与UDPTCP连接的...

  • 线程相关

    1.线程创建 继承Thread 实现Runnable接口 实现callable接口 1.1继承Thread 说下静...

  • 线程相关

    线程池:1.共有四种:Executors 2.改线程设置优先级: 3.AsyncTask的使用:线程优先级为bac...

  • 线程相关

    线程和进程有什么区别? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个...

  • 线程相关

    1、线程状态 NEW 新建状态,线程创建且没有执行start方法时的状态 RUNNABLE 可运行状态,线程已经启...

  • 线程相关

    1、用多线程的目的是什么? 充分利用cpu资源,并发做多件事 2、单核cpu机器上适不适合用多线程? 适合,如果是...

  • 线程相关

    1.创建线程的方式?通过runnable和Thread 2.Thread类中的start()和run()方法有什么...

  • 线程相关

  • 2020-07-28JDK5.0之后新增的创建多线程的方式2

    新增方式二:使用线程池 线程池相关API JDK 5.0起提供了线程池相关API:ExecutorService ...

网友评论

    本文标题:线程相关

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