我有一个练习,我必须增加一个计数器,对计数器进行平方,然后等待500毫秒再重复操作。 我被迫使用两个线程类和synchronized修饰符。 这是可能的?有人能帮我吗? 这是我的代码:
import static java.lang.Thread.sleep;
public class Sync2Thread{
private static Counter c;
static class Counter{
private int count;
public synchronized int getCount() {
return count;
}
public synchronized void incrCount() {
count++;
System.out.println("+1 => counter= "+count);
try {
sleep(500);
} catch (InterruptedException ex) {
}
}
}
public static void main (String[] args){
c = new Counter();
Thread t = new Thread(new IncrCounter());
t.start();
Thread t2 = new Thread(new Square());
t2.start();
}
/**
* Thread that increment the counter
*/
static class IncrCounter extends Thread {
public void run(){
for(int i = 0; i < 7; i++)
{
System.out.println("Current Counter = "+c.getCount());
c.incrCount();
}
}
}
/**
* Thread that calculates the square
*/
static class Square extends Thread {
public void run(){
for(int i = 0; i < 7; i++)
{
int x = c.getCount();
System.out.println(x + " squared =>"+ x*x + "\n");
yield();
}
}
}
}
我的结果类似于:
Current Counter= 0
+1 => counter= 1
Current Counter= 1
+1 => counter= 2
1 squared =>1
2 squared =>4
2 squared =>4
2 squared =>4
2 squared =>4
.....
但必须是:
Current Counter= 0
+1 => counter= 1
1 squared =>1
Current Counter= 1
+1 => counter= 2
2 squared =>4
Current Counter= 2
+1 => 3
3 squared =>9
非常感谢你
答案 0 :(得分:0)
我认为主要问题在于yield()方法。它只说“嘿,我已经完成了我的工作。如果其他一些线程需要,它现在可以进入运行状态。”因此它将线程置于可运行状态,然后查看哪些线程处于可运行状态并且可以进入运行状态。如果yield()之前的两行比另一个线程正在等待的500ms快,则square-thread将是唯一处于runnable状态的行。所以它会立即重新开始工作。
解决方案可能是让两个线程使用wait()和notify()等待彼此,或者使用sleep而不是yield。
答案 1 :(得分:0)
很少有建议:
删除synchronizaed
方法并使用AtomicInteger代替int count
。
可以原子方式更新的int值。有关原子变量属性的描述,请参阅java.util.concurrent.atomic包规范。 AtomicInteger用于诸如原子递增计数器之类的应用程序
除非在同一个线程中增加和平方或者为这两个线程使用两个不同的Counter实例,否则无法使用当前代码实现预期结果。
示例代码:(由于不同线程中的计数器访问,仍然存在副作用)
import static java.lang.Thread.sleep;
import java.util.concurrent.atomic.AtomicInteger;
public class Sync2Thread{
private static Counter c;
static class Counter{
private static AtomicInteger count = new AtomicInteger(0);
public int getCount() {
return count.get();
}
public void incrCount() {
count.incrementAndGet();
System.out.println("+1 => counter= "+getCount());
try {
sleep(500);
} catch (InterruptedException ex) {
}
}
}
public static void main (String[] args){
c = new Counter();
Thread t = new Thread(new IncrCounter());
t.start();
Thread t2 = new Thread(new Square());
t2.start();
}
/**
* Thread that increment the counter
*/
static class IncrCounter extends Thread {
public void run(){
for(int i = 0; i < 7; i++)
{
System.out.println("Current Counter = "+c.getCount());
c.incrCount();
}
}
}
/**
* Thread that calculates the square
*/
static class Square extends Thread {
public void run(){
for(int i = 0; i < 7; i++)
{
int x = c.getCount();
System.out.println(x + " squared =>"+ x*x + "\n");
c.incrCount();
}
}
}
}
输出:
Current Counter = 0
0 squared =>0
+1 => counter= 1
+1 => counter= 2
Current Counter = 2
+1 => counter= 3
3 squared =>9
+1 => counter= 4
Current Counter = 4
+1 => counter= 5
5 squared =>25
+1 => counter= 6
Current Counter = 6
6 squared =>36
+1 => counter= 7
+1 => counter= 8
8 squared =>64
Current Counter = 8
+1 => counter= 9
+1 => counter= 10
10 squared =>100
+1 => counter= 11
Current Counter = 10
+1 => counter= 12
Current Counter = 12
+1 => counter= 13
13 squared =>169
+1 => counter= 14
答案 2 :(得分:0)
正如用户Doubi所说,它适用于方法wait()和notify()。
$(document).on("click", "#select-files-upload-button", function() {
$('#select-photos').show();
});
}
输出示例:
import static java.lang.Thread.sleep;
public class Sync2Thread{
private static Counter c;
static class Counter{
private int count;
public int getCount() {
return count;
}
public void incrCount() {
count++;
System.out.println("+1 => counter= "+count);
}
}
public static void main (String[] args){
c = new Counter();
Thread t = new Thread(new IncrCounter());
t.start();
Thread t2 = new Thread(new Square());
t2.start();
}
/**
* Thread that increment the counter
*/
static class IncrCounter extends Thread {
public void run(){
for(int i = 0; i < 5; i++)
{
synchronized (c) {
try {
System.out.println("Thread1 - Current Counter = "+c.getCount());
System.out.println("Thread1 - Waiting to get notified after squared");
// This waits for the other thread perform exponentiation
c.wait();
} catch (InterruptedException ex) { }
System.out.println("Thread1 - Waiter thread got notified, let's raise!");
// As soon as the other thread has raised to a power, it increments the counter.
c.incrCount();
c.notifyAll();
}
}
System.out.println("Thread1 end___");
}
}
/**
* Thread that calculates the square
*/
static class Square extends Thread {
public void run(){
for(int i = 0; i < 5; i++)
{
synchronized (c) {
int x = c.getCount();
System.out.println("Thread2 - "+ x + " squared =>"+ x*x);
try {
sleep(500);
System.out.println("Thread2 - Sqared done, send notify\n");
c.notifyAll();
c.wait();
} catch (InterruptedException ex) { }
}
}
System.out.println("Thread2 end___");
}
}