本文主要向大家介绍了多线程的代码安全问题的解决办法
1,利用同步代码块的方式
2,调用Lock类的lock与unlock方法
那么什么是线程安全呢?
当多个线程一起运行时,在线程中的run方法,有可能运行一半,就失去了CPU的使用权,这时如果对成员变量有所操作,会影响别的线程在判断时的数据,因此会发生数据异常的情况。所以为了防止这种情况的发生,我们通过上锁的方式,将一个循环下的所有代码锁起来,保证它们是按照顺序执行下来的,这样就不会发生数据错乱的情况。
细心的同学会发现,关于同步代码块的synchronized方法的参数在什么时候用(this)在什么时候用Oject对象呢?
这也是这篇帖子的重点!!!
Runnable接口的步骤是:
1、创建任务对象
2、创建Thread线程对象参数为任务对象
3、调用start()方法,完成多线程。
所以我们在创建任务时既可以创建多个任务,也可以创建一个任务,当run方法中对成员变量有操作是,一般是创建一个任务对象,如果没有可以创建多个任务对象,这时我们要注意下面的事情:
synchronized方法中定义的锁对象,当多个线程调用时一定要保证锁对象唯一,用this当锁对象时保证创建的对象即调用线程的对象唯一,当定义一个Object类的成员变量时,就不必担心锁对象不唯一,即可以创建多个任务对象来调用线程。
我们如果用lock类进行上锁,就不可和同步代码块synchronized一起使用,会发生线程不安全异常,所以保证锁对象唯一性是至关重要的!!!
//代码实现部分;
//第一部分:
//首先定义一个线程实现Runnable接口,用同步代码块的方式实现线程安全
public class SynchronizedDemo implements Runnable{
//定义成员变量
private String name;
private String sex;
private int age;
//创建一个Object类的对象作为锁对象
Object lock = new Object();
//方法的满参构造
public SynchronizedDemo(String name,String sex,int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
//重写接口的run方法
@Override
public void run() {
// TODO Auto-generated method stub
//同步代码块
while(true) {
//用synchronized的同步代码块的方式将循环体锁住
synchronized(lock) {
System.out.println(Thread.currentThread().getName()+"运行的信息:");
System.out.println("姓名:"+name);
System.out.println("性别"+sex);
System.out.println("年龄"+age);
}
}
}
}
//第二部分:
//导包
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//创建一个类完成用lock的方法进行锁定实现线程安全
public class LockDemo implements Runnable{
//创建Lock类对象(多态);
Lock l = new ReentrantLock();
//重写接口的run方法
@Override
public void run() {
while(true){
//在循环体内上锁
l.lock();
System.out.println("第一条信息");
System.out.println("第二条信息");
System.out.println("第三条信息");
System.out.println("第四条信息");
System.out.println("第五条信息");
//调用unlock方法开锁
l.unlock();
}
}
}
//第三部分:
//测试类
//测试类进行了两种情况的练习,第一种是lock与synchronized一起用结果为线程不安全,因为创建了两个对象。
//第二种是用synchronized方法的两个不同的锁对象进行测试,如果锁对象为this且创建了两个任务对象,线程不安全。
public class Test {
public static void main(String[] args) {
SynchronizedDemo sd = new SynchronizedDemo("男枪","男",30);
SynchronizedDemo ds = new SynchronizedDemo("安妮","女",16);
//LockDemo ld = new LockDemo();
Thread t = new Thread(sd,"第一条线程");
Thread tr = new Thread(ds,"第二条线程");
//Thread th = new Thread(ld);
t.start();
//th.start();
tr.start();
}
}
|
|