我正在尝试设置 2 个线程,这些线程在另一个类中增加或减少整数。我在同步此属性时遇到了一些问题。
这是我的主要类,我在其中设置了线程和计数器类:
public class Main {
public static void main(String[] arg) {
Counter c = new Counter(10000000);
Thread1 t1 = new Thread1(c);
Runnable2 r2 = new Runnable2(c);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
System.out.println(t.getNumber());
}
}
这是我的计数器类:
public class Counter{
private int number;
private static final Object countLock = new Object();
public Counter(int number){
this.number= number;
}
public void increase(){
synchronized(countLock){
number++;
}
}
public void decrease(){
synchronized(countLock){
number--;
}
}
public int getNumber(){
return number;
}
}
这是我的 Thread1 类:(可运行的类是相同的,只是使用"实现 Runnable"而不是"扩展线程")
public class Thread1 extends Thread{
private Counter c;
public Thread1(Counter c){
this.c = c;
}
public void run(){
for(int i = 0; i < c.getNumber(); i++){
c.increase();
}
}
}
但是,我的输出始终是 10000000。即使我同步了这两种方法。有人可以解释发生了什么吗?
在启动t1.join(); t2.join();
后添加它们,以便线程在main
线程执行 sysout 之前完成其任务。
另一方面,我认为随着c.getNumber()
不断增加,线程永远不会从for loop
中出来。
我想你想拥有
int number=c.getNumber();
for(int i = 0; i < number; i++) {
而不是
for(int i = 0; i < c.getNumber(); i++) {
当我运行您的代码时,System.out.println(t.getNumber());
正在任何一个线程启动之前执行。
首先,这实际上应该永远不会结束,因为您在同一循环中增加了for
循环中用作上限的值。不确定这是否是所需的行为。
其次,您的System.out.println
将(很可能)始终打印Counter
中使用的初始值,因为线程没有时间完成其工作。出于测试目的,您可以添加类似 TimeUnit.SECONDS.sleep(10);
.对于更复杂的方法,我建议您查看java.util.concurrent.Executors
和java.util.concurrent.ExecutorService
(那里有很多示例)。
第三,如果你用java.util.concurrent.atomic.AtomicInteger
代替你的Counter
int number
,你的生活会轻松得多。