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行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**