Thread线程学习

在这里插入图片描述
线程概念:
在这里插入图片描述
线程创建的三种方式:

  1. 继承Thread类诚谢run方法
  2. 实现Runnable接口
  3. 实现Callable接口
    继承Thread类,重写run方法:
public class ThreadStart02 extends Thread {
    private String url;
    private String name;

    public ThreadStart02(String url, String name) {
        this.url = url;
        this.name = name;
    }

    @Override
    public void run(){
        WebDownLoader wd=new WebDownLoader();
        wd.downLoader(url,name);
        System.out.println(name);
    }

    public static void main(String[] args) {
        ThreadStart02 t1=new ThreadStart02("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558614086192&di=6f4bac47d0efe87d00a0bdd2d56c01e1&imgtype=0&src=http%3A%2F%2Fpic32.nipic.com%2F20130823%2F13339320_183302468194_2.jpg","first.jpg");
        ThreadStart02 t2=new ThreadStart02("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558614086192&di=50912f0854a71471859254a6c91c1a33&imgtype=0&src=http%3A%2F%2Fk.zol-img.com.cn%2Fsjbbs%2F7692%2Fa7691515_s.jpg","dog.jpg");
        ThreadStart02 t3=new ThreadStart02("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558614086192&di=b6c27e363372754becd7ac9489b2e7cd&imgtype=0&src=http%3A%2F%2Fpic40.nipic.com%2F20140412%2F18428321_144447597175_2.jpg","three.jpg");
        t1.start();
        t2.start();
        t3.start();
    }
}

实现Runnable接口

/**
 * 推荐使用接口,避免单继承的局限性
 * 方便共享资源
 */
public class ThreadStart04 implements Runnable {
    private String url;
    private String name;

    public ThreadStart04(String url, String name) {
        this.url = url;
        this.name = name;
    }

    @Override
    public void run(){
        WebDownLoader wd=new WebDownLoader();
        wd.downLoader(url,name);
        System.out.println(name);
    }

    public static void main(String[] args) {
        ThreadStart04 t1=new ThreadStart04("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558614086192&di=6f4bac47d0efe87d00a0bdd2d56c01e1&imgtype=0&src=http%3A%2F%2Fpic32.nipic.com%2F20130823%2F13339320_183302468194_2.jpg","first.jpg");
        ThreadStart04 t2=new ThreadStart04("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558614086192&di=50912f0854a71471859254a6c91c1a33&imgtype=0&src=http%3A%2F%2Fk.zol-img.com.cn%2Fsjbbs%2F7692%2Fa7691515_s.jpg","dog.jpg");
        ThreadStart04 t3=new ThreadStart04("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558614086192&di=b6c27e363372754becd7ac9489b2e7cd&imgtype=0&src=http%3A%2F%2Fpic40.nipic.com%2F20140412%2F18428321_144447597175_2.jpg","three.jpg");
        new Thread(t1).start();
        new Thread(t2).start();
        new Thread(t3).start();
    }
}

赛跑代码:

/**
 * 模拟归途赛跑
 */
public class Reacer implements Runnable {
    private static String winner;
    @Override
    public void run() {
        for(int steps=0;steps<=100;steps++){
            if(Thread.currentThread().getName().equals("兔子") && steps%10==0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+"--->"+steps);
            //比赛是否结束
            boolean flag=gameOver(steps);
            if (flag) {
                break;
            }
        }
    }
    private boolean gameOver(int steps){
        if(winner!=null){
            return true;
        }else{
            if(steps==100){
                winner=Thread.currentThread().getName();
                System.out.println("winner==>"+winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        Reacer racer=new Reacer();
        new Thread(racer,"兔子").start();
        new Thread(racer,"乌龟").start();
    }
}
Callable学习:
public class Reacer1 implements Callable<Integer> {
    private static String winner;
    @Override
    public Integer call() throws Exception {
        for(int steps=0;steps<=100;steps++){
            if(Thread.currentThread().getName().equals("pool-1-thread-1") && steps%10==0){
                Thread.sleep(100);
            }
            System.out.println(Thread.currentThread().getName()+"--->"+steps);
            //比赛是否结束
            boolean flag=gameOver(steps);
            if (flag) {
                return steps;
            }
        }
        return null;
    }
    private boolean gameOver(int steps){
        if(winner!=null){
            return true;
        }else{
            if(steps==100){
                winner=Thread.currentThread().getName();
                System.out.println("winner==>"+winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Reacer1 racer=new Reacer1();
        ExecutorService ser= Executors.newFixedThreadPool(2);
        //开始执行
        Future<Integer> result1=ser.submit(racer);
        Future<Integer> result2=ser.submit(racer);

        int r1=result1.get();
        int r2=result2.get();
        System.out.println("r1:"+r1+" r2:"+r2);
        ser.shutdown();
    }
}

代理模式:

/**
 * 静态代理
 * 接口:
 * 1,真是角色
 * 2,代理角色
 */
public class StaticProxy {
    public static void main(String[] args) {
        new WeddingCompany(new You()).happyMarry();
    }
}
interface Marry{
    void happyMarry();
}
class You implements Marry{

    @Override
    public void happyMarry() {
        System.out.println("you and 唱歌终于奔月了。。。。。");
    }
}
class WeddingCompany implements Marry{
    private Marry target;
    public WeddingCompany(Marry target){
        this.target=target;
    }
    @Override
    public void happyMarry() {
        ready();
        this.target.happyMarry();
        after();
    }

    private void ready() {
        System.out.println("布置桌子");
    }
    public void after(){
        System.out.println("结婚完毕");
    }

}

lamda表达式:
避免内部类定义过多,实质属于函数式变成的概念

public class LamdaTest05 {
    public static void main(String[] args) {
        new Thread(()->{
            for(int i=0;i<100;i++){
                System.out.println("一遍学习");
            }

        }).start();

        new Thread(()->{
            for(int i=0;i<100;i++){
                System.out.println("一遍泪流满面");
            }
        }).start();
    }
}

线程状态:
在这里插入图片描述
在这里插入图片描述
常见的线程方法:

线程的停止:
在这里插入图片描述
sleep:
1,指定当前线程阻塞的毫秒数,占有资源
2,存在中断异常InterruptedException
2,时间到后到就绪态

public class BlockStatus03 {
    public static void main(String[] args) throws InterruptedException {
        //倒数是个数。一秒一个
        Date dateTime=new Date(System.currentTimeMillis()+1000*10);
        Long end=dateTime.getTime();
        while(true){
            System.out.println(new SimpleDateFormat("mm:ss").format(dateTime));
            Thread.sleep(1000);
            dateTime=new Date(dateTime.getTime()-1000);
            if(end-10000>=dateTime.getTime()){
                break;
            }
        }
    }
    public static void test() throws InterruptedException {
        int num=10;
        while(true){
            Thread.sleep(1000);
            System.out.println(num--);
        }
    }
}

就绪状态:
1,start()方法
2,阻塞接触
3,yield()方法
4,jvm切换
运行状态:running,cpu进行控制,一般为时间分配时间片,开始运行,可以看下os的调度
阻塞状态:
1,sleep 资源占有,然后谁卖你
2,join 在那个方法,那个方法阻塞
3,wait
4,io的read 和write犯法

public class AllState {
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            for(int i=0;i<5;i++){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(".....");
            }
        });
        Thread.State state=t.getState();
        System.out.println(state);

        t.start();
        state=t.getState();
        System.out.println(state);

        while(state!=Thread.State.TERMINATED){
            int num=Thread.activeCount();
            if(num==1){
                break;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            state=t.getState();
            System.out.println(state);
        }
        state=t.getState();
        System.out.println(state);

    }
}

priority:优先级

/**
 * 新城优先级
 * 概率:知识先后执行的概率
 */
public class PriorityTest01 {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getPriority());
        MyPriority mp=new MyPriority();

        Thread t=new Thread(mp,"address");
        Thread t1=new Thread(mp,"NIKE");
        Thread t2=new Thread(mp,"回力");
        Thread t3=new Thread(mp,"361");
        Thread t4=new Thread(mp,"李宁");
        //设置优先级再启动之前
        t.setPriority(Thread.MAX_PRIORITY);
        t1.setPriority(Thread.MAX_PRIORITY);
        t2.setPriority(Thread.NORM_PRIORITY);
        t3.setPriority(Thread.MIN_PRIORITY);
        t4.setPriority(Thread.MIN_PRIORITY);
        t.start();
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
class MyPriority implements  Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());
        Thread.yield();
    }
}

线程分配

1,分为用户线程和守护线程
2,虚拟机必须确保用户线程执行完毕
‘3,虚拟机不用等待守护线程执行完毕

 * 守护线程
 * 是为用户线程服务的,JVM停止,不用等待守护线程执行完毕
 * 默认都是用户用户线程,jvm等待所有的用户线程执行完毕
 */
public class DaemonTest01 {
    public static void main(String[] args) {
        God god=new God();
        You you=new You();
        Thread t=new Thread(god);
        t.setDaemon(true);
        t.start();
        new Thread(you).start();

    }
}
class You implements Runnable{
    public void run(){
        for(int i=0;i<365*100;i++){
            System.out.println("happy life-----");
        }
        System.out.println("oooooo");
    }
}
class God implements  Runnable{
    public void run(){
        for(;true;){
            System.out.println("bresss you-----");
        }
    }
}

在这里插入图片描述’常用方法示例:

/**
 * isAlive:线程是否还活着
 * currentThread 当前线程
 * setName 设置名称:代理名称
 * 程序猿的劳斯莱斯
 */
public class InfoTest {
    public static void main(String[] args) throws InterruptedException {
        System.out.println(Thread.currentThread().isAlive());

        //设置名称:真是角色+代理角色
        myInfo info=new myInfo("站冬季");
        Thread t=new Thread(info);
        t.setName("公鸡");
        t.start();
        Thread.sleep(1000);
        System.out.println(t.isAlive());
    }
}
class myInfo implements Runnable{
    private String name;

    public myInfo(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"--->"+name);
    }
}

线程同步:
synchronized,并发控制

/**
 * 取钱线程不安全
 */
public class UnsafeTest02 {
    public static void main(String[] args) {
        Account account=new Account(100,"结婚礼金");
        Drawing you=new Drawing(account,80,"可悲的你");
        Drawing wife=new Drawing(account,90,"女朋友");
        you.start();
        wife.start();

    }
}
class Account{
    int money;
    String name;

    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }
}
class Drawing extends Thread{
    Account account;//账户
    int drawingMoney;//区签署
    int drawTotal;//取钱总数

    public Drawing(Account account, int drawingMoney,String name) {
        super(name);
        this.drawingMoney = drawingMoney;
        this.account = account;
    }

    @Override
    public void run() {
        if(account.money-drawingMoney<0){
            return;
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        account.money-=drawingMoney;
        drawTotal+=drawingMoney;
        System.out.println(this.getName()+"-->账户余额为"+account.money);
        System.out.println(this.getName()+"-->取钱总额为"+drawTotal);
    }
}
常规容易出现问题,不可避免,
女朋友-->账户余额为-70
女朋友-->取钱总额为90
可悲的你-->账户余额为-70
可悲的你-->取钱总额为80

并发原因:
1,同一个对象呗多个线程同时操作
线程同步 :当两个或两个以上线程访问同一资源时,需要某种方式来确保资源在某一时刻只被一个线程 使用。
1,队列
2,锁机制
同步监视器
• synchronized (obj){ }中的obj称为同步监视器
• 同步代码块中同步监视器可以是任何对象,但是推荐使用共享资源作为同步监视器
• 同步方法中无需指定同步监视器,因为同步方法的同步监视器是this,也就是该对象本事

同步监视器的执行过程
• 第一个线程访问,锁定同步监视器,执行其中代码
• 第二个线程访问,发现同步监视器被锁定,无法访问
• 第一个线程访问完毕,解锁同步监视器
• 第二个线程访问,发现同步监视器未锁,锁定并访问
synchronized:锁对象的资源,即this

/**
 * 数据有负数或者重复
 *
 */
public class SynTest01 {
    public static void main(String[] args) {
        SynTest0112306 web=new SynTest0112306();
        new Thread(web,"码畜").start();
        new Thread(web,"码农").start();
        new Thread(web,"码皇").start();
    }
}

class SynTest0112306 implements Runnable {
    private int ticketsNum=10;
    private boolean flag=true;
    @Override
    public void run() {
        while(flag){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            test();
        }

    }
    public synchronized void test(){
        if(ticketsNum<=0){
            flag=false;
            return;
        }
        /**
         * 模拟网络延时
         */
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"------>"+ticketsNum--);
    }

}

同步代码块:

/**
 * 取钱线程不安全
 */
public class SynTest03 {
    public static void main(String[] args) {
        Account2 account=new Account2(100,"结婚礼金");
        Drawing2 you=new Drawing2(account,80,"可悲的你");
        Drawing2 wife=new Drawing2(account,90,"女朋友");
        you.start();
        wife.start();

    }
}

class Account2{
    int money;
    String name;

    public Account2(int money, String name) {
        this.money = money;
        this.name = name;
    }
}

class Drawing2 extends Thread{
    Account2 account;//账户
    int drawingMoney;//去签署
    int drawTotal;//取钱总数

    public Drawing2(Account2 account, int drawingMoney, String name) {
        super(name);
        this.drawingMoney = drawingMoney;
        this.account = account;
    }

    @Override
    public void run() {
        test();
    }
    //目标锁定不确定,这里不应爱锁this
    public synchronized void test(){
        if(account.money-drawingMoney<0){
            return;
        }
        synchronized (account){
            if(account.money-drawingMoney<0){
                return;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            account.money-=drawingMoney;
            drawTotal+=drawingMoney;
            System.out.println(this.getName()+"-->账户余额为"+account.money);
            System.out.println(this.getName()+"-->取钱总额为"+drawTotal);
        }
    }
}

synchronized:

package syn;

/**
 * 取钱线程不安全
 */
public class SynTest03 {
    public static void main(String[] args) {
        Account2 account=new Account2(100,"结婚礼金");
        Drawing2 you=new Drawing2(account,80,"可悲的你");
        Drawing2 wife=new Drawing2(account,90,"女朋友");
        you.start();
        wife.start();

    }
}

class Account2{
    int money;
    String name;

    public Account2(int money, String name) {
        this.money = money;
        this.name = name;
    }
}

class Drawing2 extends Thread{
    Account2 account;//账户
    int drawingMoney;//去签署
    int drawTotal;//取钱总数

    public Drawing2(Account2 account, int drawingMoney, String name) {
        super(name);
        this.drawingMoney = drawingMoney;
        this.account = account;
    }

    @Override
    public void run() {
        test();
    }
    //目标锁定不确定,这里不应爱锁this
    public void test(){
        if(account.money<=0){
            return;
        }
        synchronized (account){
            if(account.money-drawingMoney<0){
                return;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            account.money-=drawingMoney;
            drawTotal+=drawingMoney;
            System.out.println(this.getName()+"-->账户余额为"+account.money);
            System.out.println(this.getName()+"-->取钱总额为"+drawTotal);
        }
    }
}

List的方法:

import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 操作容器:线程安全
 */
public class SynContainer {
    public static void main(String[] args) throws InterruptedException {
        CopyOnWriteArrayList<String> lists=new CopyOnWriteArrayList<>();
        for(int i=0;i<10000;i++){
            new Thread(()->{
                lists.add(Thread.currentThread().getName());
            }).start();
        }
        Thread.sleep(2000);
        System.out.println(lists.size());
    }
}

思索:多个线程各自占有共享资源,相互等待其他线程的资源释放,才能继续进行,导致多个线程等待对方释放资源,都停止执行,当一个同步块同时拥有两个以上的对象的锁的同时,就有可能发生思索问题。
1,问题的发生条件为锁套锁,即出现多个锁

/**
 * @author lsd
 * 思索
 */
public class DeadLock {
    public static void main(String[] args) {
        Markup g1=new Markup(1,"大牙");
        Markup g2=new Markup(0,"王菲");
        g1.start();
        g2.start();

    }
}
class Lipstick{

}
class Mirror{

}
class Markup extends Thread{
    static Lipstick lipstick=new Lipstick();
    static Mirror mirror=new Mirror();
    int choice;
    String girl;
    public Markup(int choice,String girl) {
        this.choice = choice;
        this.girl=girl;
    }
    //相互持有对方的对象锁
    public void markup(){
        if(choice==0){
            synchronized (lipstick){
                System.out.println(this.girl+"获得口红");
                //一秒后想拥有镜子的锁
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (mirror){
                System.out.println(this.girl+"获得镜子");
            }
        }else{
            synchronized (mirror){
                System.out.println(this.girl+"获得镜子");
                //一秒后想拥有镜子的锁
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (lipstick){
                System.out.println(this.girl+"获得口红");
            }
        }
    }

    @Override
    public void run(){
        markup();
    }
}

线程的写作:
生产者消费者模型:
在这里插入图片描述
在这里插入图片描述
管程法:解耦,缓冲区,互相不关联
3个角色:生产者,消费者,并发容器
信号灯法:

/**
 * 生产者消费者实现方式一:信号灯
 */
public class CodeTest02 {
    public static void main(String[] args) {
        Tv con=new Tv();
        new Player(con).start();
        new Watcher(con).start();
    }
}

//生产者 演员
class Player extends  Thread{
    Tv tv;

    public Player(Tv tv) {
        this.tv = tv;
    }

    @Override
    public void run() {
        for(int i=0;i<20;i++){
            if (i % 2 == 0) {
                try {
                    this.tv.play("奇葩说");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
                try {
                    this.tv.play("太污了,喝瓶礼拜嘻嘻最");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//消费者 观众
class Watcher extends Thread{
    Tv tv;

    public Watcher(Tv tv) {
        this.tv = tv;
    }

    @Override
    public void run() {
        for(int i=0;i<20;i++){
            if (i % 2 == 0) {
                try {
                    this.tv.watch();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
                try {
                    this.tv.watch();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//同一个资源 电视
class Tv{
    String voice;
    //信号灯 t演员表演 观众等待
    boolean flag=true;
    public synchronized void play(String voice) throws InterruptedException {
        //演员等待
        if(!flag){
            this.wait();
        }
        System.out.println("表演了"+voice);
        this.voice=voice;
        this.notifyAll();
        this.flag=!this.flag;
    }
    public synchronized void watch() throws InterruptedException {
        //观众等待
        if(flag){
            this.wait();
        }
        System.out.println("听到了"+voice);
        this.notifyAll();
        //切换标志
        this.flag=!this.flag;
    }
}

管程法:

/**
 * 生产者消费者实现方式一:管程法
 */
public class CodeTest01 {
    public static void main(String[] args) {
        SynContainer con=new SynContainer();
        new Productor(con).start();
        new Comsumer(con).start();
    }
}
//生产者
class Productor extends Thread{
    SynContainer synContainer;

    public Productor(SynContainer synContainer) {
        this.synContainer = synContainer;
    }

    @Override
    public void run() {
        for(int i=0;i<100;i++){
            System.out.println("生产第"+i+"个馒头");
            synContainer.push(new Steamedbun(i));
        }
    }
}
//消费者
class Comsumer extends  Thread{
    SynContainer synContainer;

    public Comsumer(SynContainer synContainer) {
        this.synContainer = synContainer;
    }
    @Override
    public void run() {
        for(int i=0;i<100;i++){
            System.out.println("消费第"+synContainer.pop().id+"个馒头");
        }
    }
}
//缓冲区
class SynContainer{
    Steamedbun[] bums=new Steamedbun[10];
    int count=0;//计数器
    //存储
    public synchronized void push(Steamedbun bun){
        //不能生产
        if(count==bums.length){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        bums[count]=bun;
        count++;
        this.notifyAll();
    }
    //获取
    public synchronized Steamedbun pop(){
        if(count==0){
            try {
                this.wait();//此时线程阻塞,生产者通知消费,线程阻塞
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;
        Steamedbun bun=bums[count];
        this.notifyAll();
        return bun;
    }
}
//馒头
class Steamedbun{
    int id;

    public Steamedbun(int id) {
        this.id = id;
    }
}

任务定时调度:

import java.util.*;

public class MyTimerTest01 {
    public static void main(String[] args) {
        Timer timer=new Timer();
        Calendar c=new GregorianCalendar(2099,12,31,21,53,54);
        timer.schedule(new MyTask(),c.getTime(),1000);
    }
}
//任务类,多线程
class MyTask extends TimerTask {

    @Override
    public void run() {
        for(int i=0;i<10;i++){
            System.out.println("放松大脑,放松会");
        }
        System.out.println("------end-----");
    }
}

定时器调度:spring集成

/**
 * This Example will demonstrate how to start and shutdown the Quartz scheduler and how to schedule a job to run in
 * Quartz.
 * 
 * @author Bill Kratzer
 */
public class QuartzTest {

  public void run() throws Exception {
    Logger log = LoggerFactory.getLogger(QuartzTest.class);

    log.info("------- 初始化 ---------");

    // 1,创建Scheduler工厂
    SchedulerFactory sf = new StdSchedulerFactory();
    //2,从工厂中获取调度器
    Scheduler sched = sf.getScheduler();
    // 设置时间
    Date runTime = evenSecondDate(new Date());

    // 3,创建JobDetail
    JobDetail job = newJob(HelloJob.class).withIdentity("job1", "group1").build();

    // 4.触发器
    Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(runTime).withSchedule(simpleSchedule().withIntervalInSeconds(5).withRepeatCount(3)).build();


    // 5,注册任务和触发条件
    sched.scheduleJob(job, trigger);
    sched.start();

    log.info("------- 任务调度开始 -----------------");

    // wait long enough so that the scheduler as an opportunity to
    // run the job!
    log.info("------- 5秒之后调度. -------------");
    try {
      // 5秒后停止
      Thread.sleep(65L * 1000L);
    } catch (Exception e) {
      e.printStackTrace();
    }

    log.info("------- 结束调度 ---------------------");
    sched.shutdown(true);
  }

  public static void main(String[] args) throws Exception {

    QuartzTest example = new QuartzTest();
    example.run();

  }

}

HappenBefore:
写的代码可能没按照自己想要的顺序去执行。
在这里插入图片描述
在这里插入图片描述
执行顺序:
1,获取指令
2,解码翻译 寄存器取值
3,操作
4,写回寄存器

public class HappenBerore {
    private static int a=0;
    private static boolean flag=false;
    public static void main(String[] args) throws InterruptedException {
        for(int i=0;i<100;i++){
            a=0;
            flag=false;
            Thread t=new Thread(()->{
                a=1;
                flag=true;
            });

            Thread t2=new Thread(()->{
                if(flag){
                    a*=1;
                }
                if(a==0){
                    System.out.println("happen_before  "+a);
                }
            });
            t.start();
            t2.start();
            t.join();
            t2.join();
        }

    }
}

结果为:

happen_before  1
happen_before  0
happen_before  0
happen_before  0
happen_before  0

volatile:只保证同步的数据可见。
在这里插入图片描述

/**
 * 用于保证数据的同步,也就是可见性
 * @author lsd
 */
public class VolatileTest {
    private volatile static int num=0;

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            while(num==0){
            }
        }).start();

        Thread.sleep(1000);
        num=1;
    }
}

单例模式:

/**
 * 单例模式:套路,多线程环境下对外存在一个对象
 * 1,构造器私有化--》避免外部new构造器
 * 2,提供私有的静态属性--》存储对象的地址
 * 3,提供公共的静态方法--》获取属性
 */
public class DoubleCheckedLocking {
    //私有静态属性
    private volatile static DoubleCheckedLocking instance;
    //构造器私有化
    private DoubleCheckedLocking(){

    }

    public static DoubleCheckedLocking getInstance(){
        if(instance!=null){//避免不必要的
            return instance;
        }
        synchronized(DoubleCheckedLocking.class){
            if(null==instance){
                instance=new DoubleCheckedLocking();
                //开辟空间,初始化对象信息,返回对象的地址引用
            }
        }
        return  instance;
    }

    public static void main(String[] args) {
        new Thread(()->{
            System.out.println(DoubleCheckedLocking.getInstance());
        }).start();
        System.out.println(DoubleCheckedLocking.getInstance());
    }
}

ThreadLocal:

在这里插入图片描述

/**
 * ThreadLocal:需要分析上下文环境,七点
 * 1,构造器,哪里调用就属于哪里
 */
public class ThreadLocalTest3 {
    private static ThreadLocal<Integer> threadLocal=ThreadLocal.withInitial(()->1);
    public static void main(String[] args) {
        new Thread(new MyRun()).start();
        new Thread(new MyRun()).start();
    }

    public static class MyRun implements  Runnable{
        public MyRun(){
            threadLocal.set(20);
            System.out.println(Thread.currentThread().getName()+"还剩下---->"+threadLocal.get());
        }
        @Override
        public void run() {
            Integer left=threadLocal.get();
            System.out.println(Thread.currentThread().getName()+"得到了---->"+left);
            threadLocal.set(left-1);
            System.out.println(Thread.currentThread().getName()+"还剩下---->"+threadLocal.get());
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值