如何确保一个同步块在另一个同步块之后执行



我有 Counter 类,其中包含 3 个方法,其中 2 个是同步的,我希望increment()先执行,然后再执行count(),因此每个线程的计数应始终为 3000。

与其从run()调用count(),不如从内部调用它increment()是我能想到的唯一方法,还有其他方法可以做到这一点吗?

class Counter {
int count=0;
void print() {
System.out.println("Print called by: "+Thread.currentThread().getName());
}
synchronized void increment()
{
for(int i=1;i<=3000;i++)
count++;
}
synchronized void getCount() {
System.out.println(count); 
count =0;
}
}
class MyThread1 extends Thread {
Counter c;
MyThread1(Counter c) {
this.c = c;
}
public void run() {
c.print();
c.increment();
c.getCount();
}
}
class MyThread2 extends Thread {
Counter c;
MyThread2(Counter c) {
this.c = c;
}
public void run() {
c.print();
c.increment();
c.getCount();
}
}
public class Demo {
public static void main(String args[]) {
Counter obj = new Counter();
MyThread1 t1 = new MyThread1(obj);
MyThread2 t2 = new MyThread2(obj);
t1.start();
t2.start();
}
}

每种情况下的预期 O/P:

"Print call by:"语句的打印可以按任何顺序打印,因为它没有同步,但每个线程的计数应始终为 3000

打印调用者:线程-0

打印调用者:线程-1

3000

3000

我的评论的工作示例(您不需要MyThread1和MyThread2(:

public class Demo {
public static void main(String[] args) {
Counter obj = new Counter();
MyThread t1 = new MyThread(obj);
MyThread t2 = new MyThread(obj);
t1.start();
t2.start();
}
}
class Counter {
private final ThreadLocal<Integer> count = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
}
};
void print() {
System.out.println("Print called by: " + Thread.currentThread().getName());
}
void increment() {
for (int i = 1; i <= 3000; i++)
count.set(count.get() + 1);
}
void getCount() {
System.out.println(count.get());
count.set(0);
}
}
class MyThread extends Thread {
Counter c;
MyThread(Counter c) {
this.c = c;
}
public void run() {
c.print();
c.increment();
c.getCount();
}
}
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Demo {
public static void main(String args[]) {
Counter obj = new Counter();
MyThread t1 = new MyThread(obj);
MyThread t2 = new MyThread(obj);
t1.start();
t2.start();
}
}
class Counter {
Lock lock = new ReentrantLock();
int count = 0;
void print() {
System.out.println("Print called by: " + Thread.currentThread().getName());
}
void increment() {
lock.lock();
for (int i = 1; i <= 3000; i++)
count++;
}
void getCount() {
System.out.println(count);
count = 0;
lock.unlock();
}
}
class MyThread extends Thread {
Counter c;
MyThread(Counter c) {
this.c = c;
}
public void run() {
c.print();
c.increment();
c.getCount();
}
}

您可以使用synchronized来阻止线程。

这是一个例子:

public void run() {
synchronized (Thread.class) {
c.print();
c.increment();
c.getCount();
}
}

同步需要一个对象作为参数,请对类 MyThread1 和 MyThread2 使用相同的对象

阅读 https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html 了解更多详情。

最新更新