1、什么是线程安全问题?
答:当多个线程共享同一个全局变量,对这个变量同时进行写操作时,可能会受到其他线程的干扰,这种现象叫做线程安全问题。做读操作的时候,不会产生线程安全问题
2、当多个线程共享同一个局部变量时,会发生线程安全吗?答案是,不会
3、模拟两个窗口同时卖票,也就是两个线程公用同一个全局变量y,可是这样写就出问题了哦(虽然我一开始也是这么写的,尴尬又不失礼貌的微笑)
原因如下:创建了不同的对象,每个对象有自己的变量,使用的也会是自己的变量,从而没有达到共享的目的
所以呢,应该这样写
4、使用同步的条件
1)必须有两个及两个以上的线程,而且需要发生同步
2)多个线程想同步,必须用同一把锁
3)只能保证一个线程正在执行
5、同步原理:
1)有一个线程拿到锁,其他线程在cpu中已经排好队,等待拿锁的线程释放锁
2) 锁在什么时候会释放掉?程序执行完毕或者程序执行异常被释放掉
3)锁释放掉之后,其他线程开始抢占锁,执行任务
6、线程同步的优点:解决了线程的安全问题
7、线程同步的缺点:速率特别慢
8、售票代码升级——加同步
package com.app;
public class App implements Runnable{
private int count = 100;
private Object obj = new Object();
@Override
public void run() {
while(count>0){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj) {
//if(count>0) {
System.out.println(Thread.currentThread().getName() + "正在卖--------第"+ (100-this.count+1) + "张票");
this.count--;
//}
}
}
}
public static void main(String[] args) {
App ticketWindow1 = new App();
new Thread(ticketWindow1,"窗口1").start();
new Thread(ticketWindow1,"窗口2").start();
}
}
上面代码注释掉一个判断,最后的执行结果会卖掉101张票(一共有100张票)。
我的理解是这样的:
当count=1时,线程1执行完睡眠方法(假装是买火车票出票前的一系列乱七八糟的步骤),进入同步代码块,同步块执行完count=0,锁被释放,线程二此时已在while循环里面,锁也可以用了,然后就售出了101张票
这些是我的拙见,如有问题,欢迎大家来讨论指正
为了防止出现买第101张票的情况,有两种解决办法
一、需要在同步代码块里面也要加一个判断,判断count是不是大于0。
二、将方法改为同步方法,不用代码块进行同步
至于哪一个是最好的方法,还有待进一步研究,需要根据实际情况而定
9、Synchronized 写个同步方法使用的是this锁
10、一个线程使用同步代码块,一个线程使用同步方法,两个线程可以同步吗?答案是可以,两个线程用的同一把锁时就可以做到
11、静态同步方法不能用this当锁(参考this的用法,静态方法中不能使用非静态变量)
12、两个线程,一个线程使用同步函数,另一个线程使用静态同步函数能实现同步吗?答案是不能,同步函数使用this锁,而静态函数使用当前字节码文件。
13、死锁的产生:同步中互相抢夺资源,互相不释放
14、多线程的三大特性:
原子性: 独一无二、一致性保证线程安全问题
可见性: java内存模型
有序性: join,wait,notify(多线程之间通讯)
15、什么是java内存模型?
java内存模型,决定了一个线程与另一个线程是否可见。
java内存模型分为主内存(主要存放共享的全局变量)、私有本地内存(本地线程私有变量),本地内存存放主内存中共享数据的副本
16、volatile关键字保证线程之间可见,但是不能保证线程的原子性
17、什么是线程之间的通讯?多个线程使用同一个资源(共享资源),每个线程对共享资源做的操作不同。
18、wait的作用:让当前线程从运行状态变为休眠状态
notify():让当前线程从休眠状态变为运行状态
wait和notify只能在同步(Synchronized)时使用 ,而且使用的是同一把锁
19、wait()和sleep()方法的区别?wait和sleep的功能都是使线程休眠,
wait释放锁,sleep不释放锁;
wait需要notify才能将线程从休眠状态变为运行状态,sleep时间到期后,从休眠状态变为运行状态;
sleep()方法是属于Thread类的,而wait方法是属于Object类的。
20、多线程并发(Thread)指的是操作同一个资源、 网站并发是指多个请求同时访问一台服务器
21、停止线程的思路:停止一个线程,使用Thread的stop方法不安全,可以采用手动停止线程的方法,设置一个flag,线程正常运行时,flag为true,如果想停止线程,则写一个停止线程的方法,在该方法里面将flag设置为false,这样一来,就可以停止线程了