-
关于对线程安全的理解
线程安全就是多个线程对共享数据的操作 -
举例说明
public void run() {
// TODO Auto-generated method stub
//synchronized(obj) {
//ll.lock();
for(int i = 0;i<5;i++) {
try {
//我们定义的这个线程,对count进行累加操作
count = count+i;
Thread.sleep(10);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println(count);
}
//ll.unlock();
//}
}
如果此时有两个线程对其进行操作
ThreadSafe tt = new ThreadSafe(count, obj);
//ThreadSafe tt2 = new ThreadSafe(count, obj);
new Thread(tt).start();
new Thread(tt).start();
如果不加任何控制的话,那么出现的结果会和预想的不一样,预期会出现count增加到9,但是结果却是count不会增加到9 而是会出现两个3,或者两个2,总之会出现最后增加不到9的情况
那么此时的解决思路是,在第一个线程调用的时候,不会让第二个线程再次去访问count
- 第一个解决思路
synchronized(obj) {
}
其中obj为同步监视器,其中每个类都可以做同步监视器
**而且在多个线程调用的时候,必须使用的是同一个同步监视器
- 第二个
//将其定义为一个同步方法
public Sychronized print(){
}
- 第三个
加锁
//新建锁对象
Lock ll = new ReentrantLock();
//加锁
ll.lock();
//释放锁
ll.unlock();
整体代码
package threadtest;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadSafe implements Runnable {
String count;
Object obj;
Lock ll = new ReentrantLock();
public ThreadSafe(String count,Object obj) {
// TODO Auto-generated constructor stub
this.count = count;
this.obj = obj;
}
@Override
public void run() {
// TODO Auto-generated method stub
//synchronized(obj) {
ll.lock();
for(int i = 0;i<5;i++) {
try {
count = count+i;
Thread.sleep(10);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println(count);
}
ll.unlock();
//}
}
}
测试
package threadtest;
public class Test {
public static void main(String[] args) {
String count = "0";
Object obj = new Object();
ThreadSafe tt = new ThreadSafe(count, obj);
//ThreadSafe tt2 = new ThreadSafe(count, obj);
new Thread(tt).start();
new Thread(tt).start();
//tt.start();
//tt2.start();
//tt2.start();
}
}