我正在阅读Oracle提供的官方Java Tutorial,我想将我的知识付诸实践。
我希望看到Thread Interference正在运行并使用Intrinsic Locks and Synchronization解决它。所以我创建了一个名为Counter with:
的类
public class Apple {
public static void main(String[] args) {
Counter myCounter = new Counter();
Thread a = new Thread(myCounter);
Thread b = new Thread(myCounter);
a.start();
b.start();
}
}
class Counter implements Runnable {
public int a = 0;
public int b = 0;
void incA() {
++a;
}
void decA() {
--a;
}
void incB() {
++b;
}
void decB() {
--b;
}
void printValues() {
System.out.println("a: " + a + " | b: " + b);
}
public void run() {
for (int i = 0; i < 10; i++) {
incA();
decA();
incB();
decB();
printValues();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
首先,我运行我的程序而不使用内部锁或同步,输出是我所期望的,线程干扰。
...
a: 0 | b: 0
a: 0 | b: 1
a: 0 | b: 0
a: 1 | b: 0
a: 0 | b: 0
...
现在我想使用内部锁对这个问题进行排序,这样当一个线程递增或递减a时,另一个线程可以同时改变b,而不是使用可以防止这种情况的同步方法。
所以我使用内部锁添加了两个新字段(锁)和同步块。这是新代码:
class Counter implements Runnable {
public int a = 0;
public int b = 0;
Object lock1 = new Object();
Object lock2 = new Object();
void incA() {
synchronized (lock1) {
++a;
}
}
void decA() {
synchronized (lock1) {
--a;
}
}
void incB() {
synchronized (lock2) {
++b;
}
}
void decB() {
synchronized (lock2) {
--b;
}
}
void printValues() {
System.out.println("a: " + a + " | b: " + b);
}
public void run() {
for (int i = 0; i < 10; i++) {
incA();
decA();
incB();
decB();
printValues();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
我没有对主要方法进行任何更改,所以我没有包含它。但我运行了这个代码三次,这是最后一次尝试的输出:
...
a: 0 | b: 0
a: 0 | b: 0
a: 0 | b: 1
a: 0 | b: 0
我做错了什么?代码应该如何?
我只想要一个使用内部锁的简单示例代码。
答案 0 :(得分:4)
int skip = 20;
int take=10;
List<string> filteredList = records.Skip(skip).Take(take).ToList();
读取并打印值,而另一个线程递增或递减它们:它不同步。即使它是,它也可以在对另一个线程的{{block type="catalog/product_list" column_count="4" category_id="2" block_name="home.catalog.product.list" template="izotope/products_from_category.phtml"}}
和printValues()
的调用之间读取和打印b
。
所以你可以拥有
如果没有人认为b与b不同,那么incB()
应该是单个原子操作,通过将这两个调用放在一个同步块中,并且b的读取也应该放入synchronized块,使用相同的锁:
decB()
答案 1 :(得分:1)
如何从printValues()
方法中移除run()
并在主线程中等待所有线程在打印前完成?主要是:
public static void main(String[] args) throws InterruptedException {
Counter myCounter = new Counter();
Thread a = new Thread(myCounter);
Thread b = new Thread(myCounter);
a.start();
b.start();
a.join();
b.join();
myCounter.printValues();
}