Java进阶(再论线程)——线程的4种创建方式 & 线程的生命周期 & 线程的3大特性 & 集合中的线程安全问题

3、实现Callable接口

在这里插入图片描述

package com.tianju.threadLearn;


import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/\*\*
 \* Callable,可以有返回值
 \*/
public class ThreadC implements Callable<Long> {



    @Override
    public Long call() throws Exception {
        long sum = 0;
        for (int i = 0; i < 500000; i++) {
            sum+=i;
        }
        return sum;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Long> threadC = new FutureTask<Long>(new ThreadC());
        Thread thread = new Thread(threadC);
        thread.start();
        Long aLong = threadC.get();
        System.out.println(aLong);
    }
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4、线程池

池化技术pool【常量池、数据连接池、线程池】

在这里插入图片描述

package com.tianju.threadLearn;


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PoolDemo1 {
    public static void main(String[] args) {
        System.out.println("===============缓存线程池================");
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i=0;i<10;i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread());
                }
            });
        }
        System.out.println("===============固定线程池================");
        ExecutorService executorService2 = Executors.newFixedThreadPool(1);
        for (int i=0;i<10;i++) {
            executorService2.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread());
                }
            });
        }
    }
}

二、线程的生命周期

在这里插入图片描述

join():运行结束再下一个

在这里插入图片描述

package com.tianju.threadLearn;

public class ThreadA1 extends Thread{

    static int c = 0;

    @Override
    public void run(){
        for (int i = 0; i < 20; i++) {

            try {
                System.out.println(this.getName()+": "+i);
                sleep(300);
                c++;
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadA1 a = new ThreadA1();
        a.setName("A");

        ThreadA1 b = new ThreadA1();
        b.setName("B");
        a.start();
        a.join(); // A运行结束,B才能开始运行

        b.start();
        b.join(); // 控制执行顺序

        System.out.println(Thread.currentThread().getName());
        System.out.println("c的结果为: "+c);

    }
}

在这里插入图片描述

yield():暂时让出cpu的使用权

在这里插入图片描述

package com.tianju.threadLearn;

/\*\*
 \* yield,让出cpu的使用权
 \*/
public class ThreadA2 extends Thread{

    @Override
    public void run(){
        for (int i = 0; i < 20; i++) {

            try {
                if (i%2==0){
                    // 让出cpu的使用权,避免一个线程一直占有cpu,防止独占cpu
                    // 重新竞争
                    yield();
                }
                System.out.println(this.getName()+": "+i);
                sleep(300);

            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadA2 a = new ThreadA2();
        a.setName("A");

        ThreadA2 b = new ThreadA2();
        b.setName("B");
        a.start();

        b.start();

        System.out.println(Thread.currentThread().getName());

    }
}

deamon():守护线程,最后结束

在这里插入图片描述

在这里插入图片描述

package com.tianju.threadLearn;

/\*\*
 \* 守护线程
 \* 用户线程
 \*
 \*/
public class ThreadA3 extends Thread{

    @Override
    public void run(){

        while (true){
            System.out.println("我是守护线程.......");
            try {
                sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

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

        ThreadA3 a = new ThreadA3();
        a.setName("A");
        a.setDaemon(true); // 守护线程,用户线程main结束后,他就结束了
        a.start();

        for (int i =0;i<10;i++){
            System.out.println(Thread.currentThread()+":"+i);
            Thread.sleep(200);
        }

    }
}

在这里插入图片描述

sleep():如果有锁,不会让出

在这里插入图片描述

package com.tianju.threadLearn;

public class ThreadSleep extends Thread{



    @Override
    public void run(){

        for (int i=0;i<10;i++){
            System.out.println("我是线程A:"+this.getName());

            try {
                sleep(200); // 不会让出锁
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }

    public static void main(String[] args) {
        ThreadSleep threadA = new ThreadSleep();
        threadA.setName("线程A");

        threadA.start(); // 我准备好了

        String name = Thread.currentThread().getName();
        System.out.println(name);

    }
}

三、线程的三大特性

在这里插入图片描述

原子性:AtomicInteger

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

package com.tianju.tx;

import java.util.concurrent.atomic.AtomicInteger;

/\*\*
 \* 解决原子性:AtomicInteger
 \*/
public class AtomicDemo1 {
    static AtomicInteger x= new AtomicInteger();
    static class A extends Thread{
        @Override
        public void run() {

            for (int i = 0; i < 20; i++) {
                x.incrementAndGet();
                System.out.println(getName()+ "--x:"+x);
                try {
                    sleep(200);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }
        }
    }

    public static void main(String[] args) {
        new A().start();
        new A().start();
        new A().start();
    }
}


在这里插入图片描述

CAS

CAS(Compare And Swap)

  • 从主存拷贝到工作内存(线程)
  • 修改,和主存比较,如果如果和取时结果一致,刷新到主存中。

ABA问题:

如果红色线程拿到了主存中的3,进行加1,;

蓝色线程也拿到了主存中的3,进行了加1,然后又减1;

红色线程一直问主存里面是不是3,然后发现还是3,就把4写到主存里面;

但是此时的3已经被蓝色线程动过了;

解决方案是,加一个版本号,每次被操作,就让版本号加1

在这里插入图片描述

可见性:加volatile关键字

在这里插入图片描述

package com.tianju.view;

/\*\*
 \* 线程之间不可见
 \* volatile 用于解决可见性
 \*/
public class VisibleDemo2 {
    volatile static boolean f = true; // 处理可见性,解决不了原子性
    static class A extends Thread{

        @Override
        public void run() {
            while (f){

            }
            System.out.println("A的f为:"+f);
        }
    }
    static class B extends Thread{
        @Override
        public void run() {
            f=false;
            System.out.println("B设置f为:"+f);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new A().start();
        Thread.sleep(300);
        new B().start();
    }
}


在这里插入图片描述

有序性:引用有了,对象还没

在这里插入图片描述

假设: 编译器修改顺序 1 , 3, 2

线程A执行到对象初始化阶段,还没有初始化;

线程B先获得的对象的引用,然后调用对象,

但是对象还没有初始化,因此会报错,对象初始化错误

在这里插入图片描述

四、集合中的线程安全问题

1、List集合的问题

在这里插入图片描述

在这里插入图片描述

package com.tianju.collection;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class ListDemo {
    static List<Integer> list = new ArrayList<>();

    // 有序性+原子性保证
    volatile static AtomicInteger index =new AtomicInteger(0);
    static class A extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                list.add(index.incrementAndGet());
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        A a1 = new A();
        A a2 = new A();
        A a3 = new A();
        a1.start();
        Thread.sleep(500);
        a2.start();
        a3.start();
        System.out.println(list);
    }
}


用vector解决

在这里插入图片描述

package com.tianju.collection;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;

public class VectorDemo {
    static Vector<Integer> list = new Vector<>();

    // 有序性+原子性保证
    volatile static AtomicInteger index =new AtomicInteger(0);
    static class A extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                list.add(index.incrementAndGet());
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        A a1 = new A();
        A a2 = new A();
        A a3 = new A();
        a1.start();
        a1.join(); // A运行结束,B才能开始运行
        a2.start();
        a2.join();
        a3.start();
        a3.join();
        System.out.println(list);
    }
}


用Collections.synchronizedList
package com.tianju.collection;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;

public class CollectionDemo {
    static List<Integer> ls = new ArrayList<>();
    static List<Integer> list = Collections.synchronizedList(ls);

    // 有序性+原子性保证
    volatile static AtomicInteger index =new AtomicInteger(0);
    static class A extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                list.add(index.incrementAndGet());


![img](https://img-blog.csdnimg.cn/img_convert/4433b0211098bac57e68ef657e71e9c0.png)
![img](https://img-blog.csdnimg.cn/img_convert/4f5b59fefb74ac64b6f2d27ccdc14ff0.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

 ArrayList<>();
    static List<Integer> list = Collections.synchronizedList(ls);

    // 有序性+原子性保证
    volatile static AtomicInteger index =new AtomicInteger(0);
    static class A extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                list.add(index.incrementAndGet());


[外链图片转存中...(img-15TIJYzD-1719227178953)]
[外链图片转存中...(img-sbE0zB7g-1719227178954)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值