多线程——线程安全

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,这样一来,就可以停止线程了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值