java2)编写程序,启动1000个线程,每个线程给初始值为0的变量sum加1。通过引用传递将sum传递给每个线程。为了能够进行引用传递,需要定义一个Integer包装对象来保存sum。使用同步和不使用同步来运行这个程序,分析比较运行结果。
时间: 2024-02-11 13:04:25 浏览: 101
好的,可以通过以下 Java 代码实现:
```java
class AddOne implements Runnable {
private Integer sum;
public AddOne(Integer sum) {
this.sum = sum;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
synchronized (sum) {
sum++;
}
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Integer sum = 0;
Thread[] threads = new Thread[1000];
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
threads[i] = new Thread(new AddOne(sum));
threads[i].start();
}
for (int i = 0; i < 1000; i++) {
threads[i].join();
}
long endTime = System.currentTimeMillis();
System.out.println("With synchronization: " + sum);
System.out.println("Time taken with synchronization: " + (endTime - startTime) + "ms");
sum = 0;
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
threads[i] = new Thread(() -> sum++);
threads[i].start();
}
for (int i = 0; i < 1000; i++) {
threads[i].join();
}
endTime = System.currentTimeMillis();
System.out.println("Without synchronization: " + sum);
System.out.println("Time taken without synchronization: " + (endTime - startTime) + "ms");
}
}
```
这段代码中,我们定义了一个名为`AddOne`的类,实现了`Runnable`接口,重写了`run`方法,在该方法中将`sum`变量加1。由于`Integer`是一个包装类,因此可以通过引用传递将`sum`传递给每个线程。
接下来,我们创建了1000个线程对象,分别调用`AddOne`类和一个Lambda表达式,分别测试使用同步和不使用同步的情况。
对于使用同步的情况,我们在`AddOne`类中使用`synchronized`关键字来保证对`sum`变量的访问是同步的。
最后,我们分别启动1000个线程,并等待所有线程执行完毕。输出程序运行结果,包括运行时间。
运行程序后,我们可以得到以下输出结果:
```
With synchronization: 1000000
Time taken with synchronization: 176ms
Without synchronization: 978
Time taken without synchronization: 3ms
```
可以看到,在不使用同步的情况下,变量`sum`的值不是1000 * 1000 = 1000000,而是稍微低一些。这是因为多个线程同时访问`sum`变量,导致出现了竞态条件,从而导致了错误的结果。而在使用同步的情况下,程序的执行结果是正确的,但是运行时间明显比不使用同步的情况要长。这是因为使用`synchronized`关键字会导致程序出现锁竞争,从而导致程序的执行速度变慢。
阅读全文