同步简化.

我目前正在研究线程和同步。我试图用这个程序打印“A”2次,“B”1次,“C”打印4次,这基本上是有效的,但我想知道是否有一个更小,更简单的解决方案,比如将所有类放入一个或类似的东西中。


下面是代码。


public class foo {


public static int countA = 0;

public static int countB = 0;

public static int countC = 0;



public static void main(String[] args) {



    AThread athread = new AThread(new AClass());

    BThread bthread = new BThread(new BClass());

    CThread cthread = new CThread(new CClass());


    athread.start();

    bthread.start();

    cthread.start();



}


static class AClass {


    public synchronized void printA() throws InterruptedException {

        if(countA == 2)

            wait();

        for(int i=1; i<3; i++) {

            System.out.println("A"+i);

            countA++;

        }

    }


}


static class BClass{

    public synchronized void printB() throws InterruptedException {

        if(countB == 1)

            wait();

        for(int i=1; i<2; i++) {

            System.out.println("B"+i);

            countB++;

        }

    }

}


static class CClass{ 

    public synchronized void printC() throws InterruptedException {

        if(countC == 4)

            wait();

        for(int i=1; i<5; i++) {

            System.out.println("C"+i);

            countC++;

        }

    }

}


static class AThread extends Thread {


    AClass A = new AClass();


    AThread(AClass a){

        this.A = a;

    }

    public void run() {

        try {

            A.printA();

        } catch (InterruptedException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

}

static class BThread extends Thread {


        BClass B = new BClass();


        BThread(BClass b){

            this.B = b;

        }

        public void run() {

            try {

                B.printB();

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

    }

static class CThread extends Thread {


    CClass C = new CClass();


    CThread(CClass c){

        this.C = c;

    }


POPMUISE
浏览 87回答 2
2回答

慕田峪7331174

尽管该任务不需要线程,但这里有一种使用java 8 CompletableFuture在描述中编写代码的不同方法。CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 2; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("A" + (i + 1));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }).thenRunAsync(() -> {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("B1");&nbsp; &nbsp; }).thenRunAsync(() -> {&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 5; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("C" + (i + 1));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; });

长风秋雁

正如第一条评论所说,您的任何对象之间都没有进行任何同步。也许通过更改启动线程的顺序(首先 C,然后是 B,然后是 A),这可能会变得很明显。要使线程之间的调度正常工作,您需要:找到一个对两个线程都可见的对象,以便两个线程都可以在该对象上等待()和 notify()。建立将导致等待停止的条件,并在一段时间内将其放入()所以你得到一些:while (countA < 2) AClass.class.wait();在 B 线程中(并在循环中捕获中断异常,不要传播)并在您放置的 A 线程中AClass.class.notify();在打印循环退出后。您可以(在工业环境中,大多数情况下应该)将AClass.class替换为专用于该目的的同步对象(并且已对两个线程都可见)。while() 是必要的,因为所谓的“虚假唤醒”:如果 notify() 导致它退出,则 wait() 将退出,但它也可以在没有发出此类 notify() 的情况下退出。最后,请注意,while() 循环中的条件从线程 B 访问 countA 字段,而线程 A 可能正在更新它。对于简单整数,这可能仍然是万无故障的,但对于更复杂的评估,这本身就是争用条件错误的潜在来源,因此需要依次同步这些访问。另请注意,如果线程A由于任何原因崩溃,则可能永远不会成为真,因此这不是设置内容的最可靠方法,因为它会导致系统挂起。while(countA<2)如果所有这些都更像是胡言乱语而不是英语,你应该首先尝试找到一个关于线程的体面教程,并仔细研究。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java