//实列变量共享导致的“非线程安全”问题与相应的解决方案
// 自定义线程类中的实例变量针对其他线程可以有共享与不共享之分,这在多个线程直接交互是非常重要的
//1. 不共享数据的情况
public class TestDemo extends Thread{
private int count =5;
public TestDemo(String name){
super();
this.setName(name);
}
@Override
public void run() {
super.run();
while (count>0){
count --;
System.out.println("由 "+this.currentThread().getName()+" 计算,count="+count);
}
}
}
//三个线程都有自己的变量
class Run{
public static void main(String[] args) {
TestDemo a =new TestDemo("A");
TestDemo b =new TestDemo("B");
TestDemo c =new TestDemo("C");
a.start();
b.start();
c.start();
}
}
//如何实现三个线程共同对一个count 变量进行减法操作,代码该如何设计?
//共享数据的情况:
class Mythread4 extends Thread{
private int count =5;
public Mythread4(String name){
super();
this.setName(name);
}
@Override
public void run() {
super.run();
count --;
System.out.println("由 "+this.currentThread().getName()+" 计算,count="+count);
}
}
// 线程A和B输出的结果是一致的 说明A和B同时对count进行处理,产生"非线程安全"问题
// 而我们想要的得到的输出结果是依次递减的
//出现非线程安全的情况是因为在某些JVM中,count-- 的操作要分解成如下三步(执行这三个过程的
// 步骤的过程中会被其他线程打断)
// 1.取得原有的count 值
// 2.计算count-1
// 3.对count 进行重新赋值
// 在这三个步骤中:如果有多个线程同时访问,那么很大概率会出现非线程安全的问题
//出现非线程安全的情况是多个线程操作同一个对象的同一个实例变量,导致值不准确.
class Run1{
public static void main(String[] args) {
Mythread4 a =new Mythread4("A");
Mythread4 b =new Mythread4("B");
Mythread4 c =new Mythread4("C");
Mythread4 d =new Mythread4("D");
Mythread4 e =new Mythread4("E");
a.start();
b.start();
c.start();
d.start();
e.start();
}
}
//这时就需要在多个线程之间进行同步操作
class Mythread5 extends Thread{
private int count =5;
public Mythread5(String name){
super();
this.setName(name);
}
@Override
public synchronized void run() {
super.run();
count --;
System.out.println("由 "+this.currentThread().getName()+" 计算,count="+count);
}
}
//通过run方法面前加入syncronized 关键字,使多个线程在执行run方法时,以排队的方式处理.
// 一个线程在调用run方法前,需要先判断run方法有没有上锁,如果上锁说明有其他线程在调用run方法
//必须等其他线程调用结束后才可以执行run方法
//使用syncronized 关键字修饰的方法称为”同步方法",可以用来对方法内部的全部代码进行枷锁,
// 而枷锁的这段代码称为“互斥区”或者“临界区”.
class Run2{
public static void main(String[] args) {
Mythread5 a =new Mythread5("A");
Mythread5 b =new Mythread5("B");
Mythread5 c =new Mythread5("C");
Mythread5 d =new Mythread5("D");
Mythread5 e =new Mythread5("E");
a.start();
b.start();
c.start();
d.start();
e.start();
}
}
java多线程编程18-22(实列变量共享导致的“非线程安全”问题与相应的解决方案)
最新推荐文章于 2024-11-03 11:01:20 发布