标签:线程安全问题
1.多线程-线程安全问题演示
多个线程对象运行同一个线程任务代码的时候,一个线程运行到判断语句后被临时阻塞了,下个线程继续判断,直接输出结果,前一个线程再输出的结果,可能会出问题
class Ticket implements Runnable{
private int num = 100;
public void run(){
while(true){
if(num>0){
try{
Thread.sleep(10);
}catch(InterruptedException e){}
//让线程在这里小睡,导致了 0 -1 等错误票的产生。
//出现了线程安全问题。
System.out.println(Thread.currentThread().getName()+"..sale:"+num--);
}
}
}
}class ThreadDemo3_Ticket_Runnable{
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
//多个线程对象调用同一个线程任务
}
}2.多线程-线程安全问题原因
原因:
1.多个线程在同时处理共享数据。
2.线程任务中的有多条代码在操作共享数据。
安全问题成因就是:一个线程在通过多次操作共享数据的过程中,其他线程参与了共享数据的操作。
导致到了数据的错误.
想要知道你的多线程程序有没有安全问题:
只要看线程任务中是否有多条代码在处理共享数据。
3.多线程-线程安全问题-同步代码块解决
解决:
一个线程在通过多条语句操作共享数据的过程中,不允许其他线程参与运算。
如何代码体现呢?
Java中提供了同步代码块进行引起安全问题的代码封装。
格式:
synchronized(对象) //该对象是任意的
{
//需要被同步的代码;
}class Ticket implements Runnable{
private int num = 100;
Object obj = new Object();
public void run(){
while(true){
synchronized(obj){
if(num>0){
try{
Thread.sleep(10);
}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"..sale:"+num--);
}
}
}
}
}
class ThreadDemo4_Ticket_Safe{
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}4.多线程-线程安全问题-同步代码块好处&弊端&前提
同步好处:解决了多线程的安全问题。
同步弊端:降低了效率。
同步的前提:
1.至少有两个线程在同步中。
2.必须保证同步使用的是同一个锁。
synchronized(new Object()){
}
意思是让每个线程进到同步代码块中,就会换一把新锁。有安全隐患,没有保障多线程直接使用用一把锁。
5.多线程-线程安全问题-同步函数使用的锁
同步的第二种表现形式:同步函数。
问题:同步函数使用的锁是什么呢?
同步函数使用的锁,应该是this。
同步函数和同步代码块的区别?
同步函数使用的固定锁this。
同步代码块使用的锁是可以指定的。
class Ticket implements Runnable{
private int num = 100;
boolean flag = true;
Object obj = new Object();
public void run(){
if(flag){
while(true){
synchronized(this){
if(num>0){
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"..obj:"+num--);
}
}
}
}else{
while(true){
this.sale();
}
}
}
public synchronized void sale(){//同步函数。
if(num>0){
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"..func:"+num--);
}
}
}class ThreadDemo5_Ticket_SynFunction{
public static void main(String[] args){
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{Thread.sleep(10);}catch(InterruptedException e){}
t.flag = false;
t2.start();
}
}6.多线程-线程安全问题-静态同步函数使用的锁
静态同步函数使用的锁是什么?
就是所在类的 类名.class 字节码文件对象。
class Ticket implements Runnable{
private static int num = 100;
boolean flag = true;
public void run(){
if(flag){
while(true){
synchronized(Ticket.class)//super.getClass(){
if(num>0){
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"..obj:"+num--);
}
}
}else{
while(true) {
this.sale();
}
}
}
public static synchronized void sale(){//static同步函数。
if(num>0){
try{Thread.sleep(10);}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"..func:"+num--);
}
}
}
class ThreadDemo5_Ticket_StaticLock{
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{Thread.sleep(10);}catch(InterruptedException e){}
t.flag = false;
t2.start();
}
}7.多线程-线程安全问题-单例懒汉式多线程问题
//饿汉式,不会出现线程安全问题,没有多条共享数据
class Single1{
private static final Single1 s = new Single1();
private Single1(){}
public static Single1 getInstance(){
return s;
}
}
//懒汉式
/*
加同步关键字,解决的是安全问题。
public static Single getInstance() {if(s==null) {s = new Single();} }
加双重判断,是为了提高效率,不用每次都进入同步代码块。
*/
class Single2{
private static Single2 s = null;
private Single2(){}
public static Single2 getInstance(){
//当存在对象时,执行到第一个if语句判断条件不符合后,不用进入下面的同步代码块
if(s==null){
synchronized(Single.class){
if(s==null){
s = new Single();
}
}
}
return s;
}
}
14-多线程-线程安全问题-死锁示例
class Demo implements Runnable{
private boolean flag;
Demo(boolean flag){
this.flag = flag;
}
public void run(){
if(flag){
while(true){
synchronized(MyLock.LOCKA){
System.out.println("if locka");
synchronized(MyLock.LOCKB){
System.out.println("if lockb");
}
}
}
}else{
while(true){
synchronized(MyLock.LOCKB){
System.out.println("else lockb");
synchronized(MyLock.LOCKA){
System.out.println("else locka");
}
}
}
}
}
}
class MyLock{
public static final Object LOCKA = new Object();
public static final Object LOCKB = new Object();
}
class ThreadDemo8_DeadLock {
public static void main(String[] args) {
Demo d1 = new Demo(true);
Demo d2 = new Demo(false);
Thread t1 = new Thread(d1);
Thread t2 = new Thread(d2);
t1.start();
t2.start();
}
}标签:线程安全问题
原文地址:http://8477424.blog.51cto.com/8467424/1773165