1.多线程之睡眠插队守护线程

1.process进程(程序) thread线程

main线程

2.多线程是是模拟处理的,真正的多线程是物理上的几个线程

1.线程不能人为干预
2.每个线程内存交互,控制不当数据不一致

3.实现

  1. extend Thread(oop单继承局限性) 重写run方法(与main线程交替执行)
    1. 如果不是多线程 按代码执行顺序执行
    2. 线程开启不一定立即执行,由cpu调度
    3. 网上图片变文件 多线程下载

  2. Runnable(推荐)(可以多个线程操作同一个对象,会有线程重复消费问题)
    1.new Thread(xxximplRunable).start();;

  3. Callable 工作3 5年后的重点

    1. 实现Callable 定义返回类型
    2. 重写call方法 public Boolean call(){ return true;}
    3. 创建执行访问
      ser=Executors.newFixedThreadPool(3);
    4. 提交执行任务
      Future r1=ser.submit(t1);
      Future r2=ser.submit(t2);
    5. 获得执行结果
      boolean res1=r1.get();
      boolean res2=r2.get();
    6. 关闭服务
      ser.shutdownNow();

4.龟兔赛跑

    if(){
	
   }//有return,else可以省略

5.静态代理模式(设计模式的装饰模式) 好处 代替真实对象做,还可以做一些真实对象不能做的

class staticProxy{
    public static void main(String[] args) {
        WeddingCompany weddingCompany = new WeddingCompany(new You());
        weddingCompany.happyMarry();
        //和线程一样的道理
        new Thread(()->{
            System.out.println("结婚拉");
        }).start();
    }
}
public interface Marry {
     void happyMarry();
}
class You implements Marry{
    @Override
    public void happyMarry() {
        System.out.println("小狂神要要结婚了");
    }
}
class  WeddingCompany implements Marry{

    private Marry target;

    public  WeddingCompany(Marry target){ //构造方法没有返回值
        this.target=target;
    }

    private void before() {
        System.out.println("结婚前整理现场");
    }
    private void after() {
        System.out.println("结婚后收取费用");
    }
    @Override
    public void happyMarry() {
        before();
        this.target.happyMarry();
        after();

    }
}

6.lambda表达式(匿名内部类)(一个方法的接口就是函数式接口)
进化过程

  1. 一个类一个接口 ,类实现接口
  2. 静态内部类,在类里面写静态方法 实现接口
  3. 局部内部类 直接在方法里面写类 都可以new出来
  4. 匿名内部类
    new xx(){xxx};//接口可以new出来
  5. lambda (方法的参数 int a)->{xxx}; (方法的参数 a)->{xxx}; //去参数类型,多个参数要去都去
    a->{} //去括号,只有一个参数时
    a->xxx //去花括号,只有一行时

7.线程的状态 5个状态 sleep() wait()可以进入阻塞状态
//线程怎么停止,不建议使用 jdk自己的stop()方法
//写个while(flag)死循环+标志物模拟即可

   public class ThreadStop {
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        new Thread(myThread).start();
        for (int i = 0; i < 100000; i++) {
            if (i==99999){
                myThread.stop();
            }
        }


    }


}
class MyThread implements Runnable{
    boolean flag=true;
    int i=0;
    @Override
    public void run() {
        while(flag){
            System.out.println("程序运行中"+i);

            i++;

        }

    }
    public void stop(){
        flag=false;
    }
}

8.线程睡眠 sleep 可以放大问题的发生性,每个对象都有一个锁,sleep不会释放锁

9.yield礼让, a使用cpu中然后礼让b,和b在就绪状态继续竞争(不一定成功 看cpu心情)
//如果又得到cpu了,那继续执行下面的代码

public class ThreadYield {
    public static void main(String[] args) {

        new Thread(new MyThread3(),"a").start();
        new Thread(new MyThread3(),"b").start();
    }
}
class MyThread3 implements Runnable{

    @Override
    public void run() {

            System.out.println(Thread.currentThread().getName()+"线程让步前");
            Thread.yield();
            System.out.println(Thread.currentThread().getName()+"线程让步后");



    }
}

10.join强制插队(非常霸道,必须要强制执行完他)不推荐使用,会让其他线程阻塞
//注意是new出来后才有的方法join()代表现在这个对象,要强行插队

public class ThreadJoin {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new MyThread4());
        thread.start();
        for (int i = 0; i < 100; i++) {
            if (i==20){
                thread.join();
            }
            System.out.println(Thread.currentThread().getName()+i);
        }
    }


}
class MyThread4 implements Runnable{

    @Override
    public void run() {

        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }

    }
}

11.观察Thread的状态 5.for 死亡后不能再启动

 Thread.State state=thread.getState(); 

12.优先级(设置,不一定一定优先,只是概率高,就算放在后面概率也高) 范围[1,10] main默认是5公平
//得到优先级

     Thread.currentThread().getPriority();
   //注意先设置优先级后启动
     t1.setPriotity(1);
     t1.start();

13.守护线程 daemon线程

  1. 用户线程main线程,任务结束就停止
  2. 守护线程 gc 日志记录线程 监控内存… 永不停止
    thread.setDaemon(true);//设置是守护线程,用户结束了,jvm不用管守护线程,程序结束了jvm就结束了,上帝就结束了 god blessed with me 就是守护线程一直守护用户线程,用户线程消失,上帝守护线程也消失
    人生不过3万天…
  1. 线程同步(对象等待池形成队列)队列+锁保证线程安全,数可能会负数或者重复消费,因为同一时间操作相同对象
  1. 并发: 多个线程访问同一个对象(一拥而上)
  2. 线程并发加锁的问题:
    1. 一个拥有锁会导致其他需要这个锁的线程挂起
    2. 加锁释放锁需要很多的上下文切换和调度延时,有性能问题
    3. 优先级高的锁等低优先级的锁,会导致性能低下,有性能问题
  3. 三大不安全案例 取票 银行同时多个线程取钱 ArrayList线程不安全
    4.for
    new Thread(()->{list.add(Thread.currentThread().getName())});
    sout(list.size);//数量丢失,当超多线程同时访问的时候,创建多个线程操作同一list

15.同步方法

  1. private保证对象只能被方法访问(get set方法)
  2. 声明synchronized在方法上会影响效率,默认锁的是整个this对象,应该锁我们需要的,不然失效(锁this)
  3. 使用同步块,以上面list为例,锁的是需要 增删改的对象
    synchronized(list){
    }

15.JUC是并发包,写好了线程安全的东西 CopyOnWriteArrayList是线程安全的list

可以直接使用
transient有序的 volatile唯一的 java关键字

你可能感兴趣的:(java,并发)