《java多线程编程核心技术》四 多个线程共享数据
实例一:
package com.blog.damingge.example.thread;
public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread a = new Thread(myThread,"A线程");
Thread b = new Thread(myThread,"B线程");
Thread c = new Thread(myThread,"C线程");
Thread d = new Thread(myThread,"D线程");
Thread e = new Thread(myThread,"E线程");
a.start();
b.start();
c.start();
d.start();
e.start();
System.out.println("主线程运行结束");
}
}
package com.blog.damingge.example.thread;
public class MyThread extends Thread{
private int count = 100;
@Override
public void run() {
System.out.println();
count-- ;
System.out.println(Thread.currentThread().getName() +"正在执行,count值为" +count);
}
}
执行结果(多次运行结果不同)如下:
A线程正在执行,count值为98
B线程正在执行,count值为98
C线程正在执行,count值为97
主线程运行结束
E线程正在执行,count值为96
D线程正在执行,count值为95
结论:
1)与我们期望的count依次减一不同,存在非线程安全问题。
2)count--操作,JVM是分三步进行的,第一步获取count的原值,第二步对count进行减一操作,第三步用新值替代旧值。
实例二:
如何使实例一达到预期的依次减1呢,最简单的方法是在run方法上加synchronize关键字,使线程排队执行run方法(即在方法上加锁,一个线程获取到该run方法的锁后,其他线程只能等待持锁线程执行完毕,或失去锁时,其他线程才可以争抢锁,进而执行run方法)
加锁的代码称为“临界区”
package com.blog.damingge.example.thread;
public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread a = new Thread(myThread,"A线程");
Thread b = new Thread(myThread,"B线程");
Thread c = new Thread(myThread,"C线程");
Thread d = new Thread(myThread,"D线程");
Thread e = new Thread(myThread,"E线程");
a.start();
b.start();
c.start();
d.start();
e.start();
System.out.println("主线程运行结束");
}
}
package com.blog.damingge.example.thread;
public class MyThread extends Thread{
private int count = 100;
@Override
synchronized public void run() {
count-- ;
System.out.println(Thread.currentThread().getName() +"正在执行,count值为" +count);
}
}
执行结果:
A线程正在执行,count值为99
D线程正在执行,count值为98
主线程运行结束
C线程正在执行,count值为97
B线程正在执行,count值为96
E线程正在执行,count值为95
浙公网安备 33010602011771号