线程同步问题

线程同步:多个线程操作同一资源

并发:同一个对象被多个线程同时操作

解决线程同步问题的核心,是让线程排好队一个个来(队列),同时还要使用锁确保安全。

要确保线程安全,必然会降低效率。

 

线程同步

方式一:使用synchronized修饰方法或代码块

每个对象都有一把锁,使用synchronized修饰方法,必须获取这个锁才能执行,没有获取到锁的线程阻塞。但如果对大的方法使用这套机制会影响效率,只读操作不需要加锁,给修改操作的代码块加锁即可。

使用synchronized默认锁的是this(类),但有时并不是这个类本身进行了增删改,所以使用锁最难的就是分析哪个对象需要进行增删改,再将这个对象加锁。

 

疑问点:new 了一个list,给list加synchonized代码块,如果不通过sleep延迟,打印时list数据仍然可能少。

public class UnsafeList {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(() -> {
synchronized (list){
list.add("1");
}
}).start();
}
//try {
// Thread.sleep(1000);
//} catch (InterruptedException e) {
// e.printStackTrace();
//}
System.out.println(list.size()); //9999
}
}

解答:给list添加数据的线程还没执行完,main线程先跑了,所以打印出来会少。通过给main线程加sleep,这样可以确保数据全部添加完才打印最终结果。

public class TestThread {
public static void main(String[] args) {
new Thread(()->{
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "线程睡醒了");
}).start();
System.out.println(Thread.currentThread().getName() + "执行完毕");
}
}

main执行完毕
Thread-0线程睡醒了

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2022-05-28 17:41  浅枫  阅读(48)  评论(0编辑  收藏  举报