Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 3个线程按顺序打印备用值_Java_Multithreading - Fatal编程技术网

Java 3个线程按顺序打印备用值

Java 3个线程按顺序打印备用值,java,multithreading,Java,Multithreading,我试图创建一个实现,其中多个线程打印序列的备用值。这里thread1将打印1,4,7 thread2将打印2,5,8 thread3将打印3,6,9。我使用的是原子整数和模函数 在第一个线程打印1,4,7,而第二个线程打印2,5,8,第三个线程打印3,6,9的意义上,下面的实现工作得很好,但问题是没有保持顺序,即输出可能类似于1,3,2,4,5,7,8,6,9,而我希望保持顺序,因为正确的线程可以打印这些值。 一个条件是我不想使用同步。[仅用于学习目的] import java.util.con

我试图创建一个实现,其中多个线程打印序列的备用值。这里thread1将打印1,4,7 thread2将打印2,5,8 thread3将打印3,6,9。我使用的是原子整数和模函数

在第一个线程打印1,4,7,而第二个线程打印2,5,8,第三个线程打印3,6,9的意义上,下面的实现工作得很好,但问题是没有保持顺序,即输出可能类似于1,3,2,4,5,7,8,6,9,而我希望保持顺序,因为正确的线程可以打印这些值。 一个条件是我不想使用同步。[仅用于学习目的]

import java.util.concurrent.atomic.AtomicInteger;

public class ThreeThreadsOrderedLockLess {

    AtomicInteger sharedOutput = new AtomicInteger(0);

    public static void main(String args[]) {



        ThreeThreadsOrderedLockLess t = new ThreeThreadsOrderedLockLess();



        ThreadTasks t1 = t.new ThreadTasks(0);
        ThreadTasks t2 = t.new ThreadTasks(1);
        ThreadTasks t3 = t.new ThreadTasks(2);

        Thread ts1 = new Thread(t1);
        Thread ts2 = new Thread(t2);
        Thread ts3 = new Thread(t3);
        ts1.start();
        ts2.start();
        ts3.start();

    }

    private class ThreadTasks implements Runnable {

        private final int threadPosition;


        public ThreadTasks(int threadPosition) {
            super();

            this.threadPosition = threadPosition;
        }

        @Override
        public void run() {

            while (sharedOutput.get() < 9) {

                if (sharedOutput.get() % 3 == this.threadPosition) {

                    System.out.println("Printing output for Thread: "
                            + this.threadPosition + "  "
                            + sharedOutput.incrementAndGet());
                }
            }

        }
    }

}

这是因为每个线程的时间片由操作系统决定。因此,线程x可能会增加共享编号,但在打印之前,时间片会传递给下一个线程y,该线程现在读取共享编号,并在增加后打印它,假设线程y比线程x有更多的时间来增加和打印共享编号
这是因为每个线程的时间片由操作系统决定。因此,线程x可能会增加共享编号,但在打印之前,时间片会传递给下一个线程y,该线程现在读取共享编号,并在增加后打印它,假设线程y比线程x有更多的时间来增加和打印共享编号
.

您应该先打印,然后递增:

int value = sharedOutput.get() + 1;
System.out.println("Printing output for Thread: "
                        + this.threadPosition + "  "
                        + value);
sharedOutput.incrementAndGet();

也就是说,所有线程都忙于循环,这将导致100%的CPU使用率。您应该同步线程。

您应该先打印,然后递增:

int value = sharedOutput.get() + 1;
System.out.println("Printing output for Thread: "
                        + this.threadPosition + "  "
                        + value);
sharedOutput.incrementAndGet();
也就是说,所有线程都忙于循环,这将导致100%的CPU使用率。您应该改为同步线程。

使用wait、notify、notify Java的所有方法。 你也可以看看这些方法中的这个

希望这将有助于解决您的问题

此示例的输出如下所示

Put:1 得到:1 Put:2 得到:2 Put:3 得到:3 Put:4 得到:4 Put:5 Got:5使用wait、notify、notifyJava的所有方法。 你也可以看看这些方法中的这个

希望这将有助于解决您的问题

此示例的输出如下所示

Put:1 得到:1 Put:2 得到:2 Put:3 得到:3 Put:4 得到:4 Put:5 得到:5这应该可以:

package com.sid;

import java.util.concurrent.atomic.AtomicInteger;

public class NumberSequence {

    private AtomicInteger sharedOutput = new AtomicInteger(0);
    private Object object = new Object();

    public static void main(String args[]) {

        NumberSequence t = new NumberSequence();

        ThreadTasks t1 = t.new ThreadTasks(0);
        ThreadTasks t2 = t.new ThreadTasks(1);
        ThreadTasks t3 = t.new ThreadTasks(2);

        Thread ts1 = new Thread(t1);
        Thread ts2 = new Thread(t2);
        Thread ts3 = new Thread(t3);

        ts1.start();
        ts2.start();
        ts3.start();

    }

    private class ThreadTasks implements Runnable {

        private final int threadPosition;

        public ThreadTasks(int threadPosition) {
            super();

            this.threadPosition = threadPosition;
        }

        @Override
        public void run() {

            while (sharedOutput.get() < 10) {

                synchronized (object) {

                    if (sharedOutput.get() % 3 == this.threadPosition) {

                        if(sharedOutput.get() < 10)
                        System.out.println("Printing output for Thread: "
                                + this.threadPosition + "  "
                                + sharedOutput.incrementAndGet());
                    }
                }
            }

        }
    }

}
这应该起作用:

package com.sid;

import java.util.concurrent.atomic.AtomicInteger;

public class NumberSequence {

    private AtomicInteger sharedOutput = new AtomicInteger(0);
    private Object object = new Object();

    public static void main(String args[]) {

        NumberSequence t = new NumberSequence();

        ThreadTasks t1 = t.new ThreadTasks(0);
        ThreadTasks t2 = t.new ThreadTasks(1);
        ThreadTasks t3 = t.new ThreadTasks(2);

        Thread ts1 = new Thread(t1);
        Thread ts2 = new Thread(t2);
        Thread ts3 = new Thread(t3);

        ts1.start();
        ts2.start();
        ts3.start();

    }

    private class ThreadTasks implements Runnable {

        private final int threadPosition;

        public ThreadTasks(int threadPosition) {
            super();

            this.threadPosition = threadPosition;
        }

        @Override
        public void run() {

            while (sharedOutput.get() < 10) {

                synchronized (object) {

                    if (sharedOutput.get() % 3 == this.threadPosition) {

                        if(sharedOutput.get() < 10)
                        System.out.println("Printing output for Thread: "
                                + this.threadPosition + "  "
                                + sharedOutput.incrementAndGet());
                    }
                }
            }

        }
    }

}

正确的同步将帮助您获得清晰的答案。我已经改进了实施,你应该解决你的问题

    int threadId;
    int moduluos;
    int numOfThreads;

    public ThreadTasks(int id, int nubOfThreads) {
        threadId = id;
        this.numOfThreads = nubOfThreads;
        moduluos = threadId%numOfThreads;
    }

    public void run() {
        print();
    }

    private void print() {
        try {
            while (true) {
                synchronized (monitor) {
                    if (number.get() % numOfThreads != moduluos) {
                        monitor.wait();
                    } else {
                        System.out.println("ThreadId [" + threadId
                                + "] printing -->"
                                + number.getAndIncrement());
                        monitor.notifyAll();
                    }
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

正确的同步将帮助您获得清晰的答案。我已经改进了实施,你应该解决你的问题

    int threadId;
    int moduluos;
    int numOfThreads;

    public ThreadTasks(int id, int nubOfThreads) {
        threadId = id;
        this.numOfThreads = nubOfThreads;
        moduluos = threadId%numOfThreads;
    }

    public void run() {
        print();
    }

    private void print() {
        try {
            while (true) {
                synchronized (monitor) {
                    if (number.get() % numOfThreads != moduluos) {
                        monitor.wait();
                    } else {
                        System.out.println("ThreadId [" + threadId
                                + "] printing -->"
                                + number.getAndIncrement());
                        monitor.notifyAll();
                    }
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

使用阻塞队列可以更好地实现这一点。定义持有阻塞队列的工作进程。工人在队列上等待,直到队列中收到一个数字。它打印接收到的数字,增加数字,并将其传递给链中的下一个工人。请参阅完整的解决方案

使用阻塞队列可以更好地实现这一点。定义持有阻塞队列的工作进程。工人在队列上等待,直到队列中收到一个数字。它打印接收到的数字,增加数字,并将其传递给链中的下一个工人。请参阅完整的解决方案

下面的代码片段将按顺序打印数字,所有线程将在任务完成后优雅地终止。 使用AtomicInteger,它对于打印数字是线程安全的,并且相同的逻辑可以应用于打印任何带有任意线程数的数字

import java.util.concurrent.atomic.AtomicInteger; public class PrintNumSequence { public static void main(String[] args) { AtomicInteger atomicInteger = new AtomicInteger(0); new NumPrinter(atomicInteger, 0).start();// thread0 new NumPrinter(atomicInteger, 1).start();// thread1 new NumPrinter(atomicInteger, 2).start();// thread2 } } class NumPrinter extends Thread { private AtomicInteger atomicInteger; private int threadNum; public NumPrinter(AtomicInteger atomicInteger, int threadNum) { this.atomicInteger = atomicInteger; this.threadNum = threadNum; } @Override public void run() { int num = atomicInteger.intValue(); do { synchronized (atomicInteger) { num = atomicInteger.intValue(); // If number is 9 then stop. if (num > 9) { atomicInteger.notifyAll(); break; } // 3 is number of threads if ((num % 3) == threadNum) { System.out.println("Thread-" + threadNum + " -->" + num); num = atomicInteger.incrementAndGet(); } atomicInteger.notifyAll(); try { atomicInteger.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } while (true); } }
下面的代码片段将按顺序打印数字,所有线程将在任务完成后优雅地终止。 使用AtomicInteger,它对于打印数字是线程安全的,并且相同的逻辑可以应用于打印任何带有任意线程数的数字

import java.util.concurrent.atomic.AtomicInteger; public class PrintNumSequence { public static void main(String[] args) { AtomicInteger atomicInteger = new AtomicInteger(0); new NumPrinter(atomicInteger, 0).start();// thread0 new NumPrinter(atomicInteger, 1).start();// thread1 new NumPrinter(atomicInteger, 2).start();// thread2 } } class NumPrinter extends Thread { private AtomicInteger atomicInteger; private int threadNum; public NumPrinter(AtomicInteger atomicInteger, int threadNum) { this.atomicInteger = atomicInteger; this.threadNum = threadNum; } @Override public void run() { int num = atomicInteger.intValue(); do { synchronized (atomicInteger) { num = atomicInteger.intValue(); // If number is 9 then stop. if (num > 9) { atomicInteger.notifyAll(); break; } // 3 is number of threads if ((num % 3) == threadNum) { System.out.println("Thread-" + threadNum + " -->" + num); num = atomicInteger.incrementAndGet(); } atomicInteger.notifyAll(); try { atomicInteger.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } while (true); } }
我把代码打印1-100使用5线程。可以使用任意数量的线程以循环方式打印输出

基本概念是锁定一个对象并通知另一个对象以执行值的打印

public class PrintOneToHundredUsing5Threads {

    public static void main(String[] args) {
        List<Object> objList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            objList.add(new Object());
        }
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new PrintThread(objList.get(i), objList.get((i + 1) % 5)));
            t.setName("Thread" + i);
            t.start();
        }
    }

}

class PrintThread implements Runnable {
    Object current;
    Object next;
    volatile static int i = 1;

    PrintThread(Object cur, Object next) {
        this.current = cur;
        this.next = next;
    }

    @Override
    public void run() {
        for (; i <= 100;) {
            synchronized (current) {
                synchronized (next) {
                    next.notify();
                    System.out.println(Thread.currentThread().getName() + " Value : " + i++);
                }
                try {
                    current.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }

}

我把代码打印1-100使用5线程。可以使用任意数量的线程以循环方式打印输出

基本概念是锁定一个对象并通知另一个对象以执行值的打印

public class PrintOneToHundredUsing5Threads {

    public static void main(String[] args) {
        List<Object> objList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            objList.add(new Object());
        }
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new PrintThread(objList.get(i), objList.get((i + 1) % 5)));
            t.setName("Thread" + i);
            t.start();
        }
    }

}

class PrintThread implements Runnable {
    Object current;
    Object next;
    volatile static int i = 1;

    PrintThread(Object cur, Object next) {
        this.current = cur;
        this.next = next;
    }

    @Override
    public void run() {
        for (; i <= 100;) {
            synchronized (current) {
                synchronized (next) {
                    next.notify();
                    System.out.println(Thread.currentThread().getName() + " Value : " + i++);
                }
                try {
                    current.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }

}

您可以使用以下代码使用多个线程打印序列号-

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ThreadCall extends Thread {

    private BlockingQueue<Integer> bq = new ArrayBlockingQueue<Integer>(10);
    private ThreadCall next;

    public void setNext(ThreadCall t) {
        this.next = t;
    }

    public void addElBQ(int a) {
        this.bq.add(a);
    }

    public ThreadCall(String name) {
        this.setName(name);
    }

    @Override
    public void run() {
        int x = 0;
        while(true) {
            try {
                x = 0;
                x = bq.take();
                if (x!=0) {
                    System.out.println(Thread.currentThread().getName() + " =>" + x);
                    if (x >= 100) System.exit(0); // Need to stop all running threads
                    next.addElBQ(x+1);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        int THREAD_COUNT = 10;
        List<ThreadCall> listThread = new ArrayList<>();

        for (int i=1; i<=THREAD_COUNT; i++) {
            listThread.add(new ThreadCall("Thread " + i));
        }

        for (int i = 0; i < listThread.size(); i++) {
            if (i == listThread.size()-1) {
                listThread.get(i).setNext(listThread.get(0));
            }
            else listThread.get(i).setNext(listThread.get(i+1));
        }

        listThread.get(0).addElBQ(1);

        for (int i = 0; i < listThread.size(); i++) {
            listThread.get(i).start();
        }
    }
}

希望这能解决您的问题。

您可以使用以下代码使用多线程打印序列号-

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ThreadCall extends Thread {

    private BlockingQueue<Integer> bq = new ArrayBlockingQueue<Integer>(10);
    private ThreadCall next;

    public void setNext(ThreadCall t) {
        this.next = t;
    }

    public void addElBQ(int a) {
        this.bq.add(a);
    }

    public ThreadCall(String name) {
        this.setName(name);
    }

    @Override
    public void run() {
        int x = 0;
        while(true) {
            try {
                x = 0;
                x = bq.take();
                if (x!=0) {
                    System.out.println(Thread.currentThread().getName() + " =>" + x);
                    if (x >= 100) System.exit(0); // Need to stop all running threads
                    next.addElBQ(x+1);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        int THREAD_COUNT = 10;
        List<ThreadCall> listThread = new ArrayList<>();

        for (int i=1; i<=THREAD_COUNT; i++) {
            listThread.add(new ThreadCall("Thread " + i));
        }

        for (int i = 0; i < listThread.size(); i++) {
            if (i == listThread.size()-1) {
                listThread.get(i).setNext(listThread.get(0));
            }
            else listThread.get(i).setNext(listThread.get(i+1));
        }

        listThread.get(0).addElBQ(1);

        for (int i = 0; i < listThread.size(); i++) {
            listThread.get(i).start();
        }
    }
}

希望这能解决您的问题。

ThreadSynchronization类可用于按顺序打印“n”个线程之间的数字。 逻辑是在每个连续线程之间创建一个公共对象,并使用“等待”、“通知”按顺序打印数字。 注意:最后一个线程将与第一个线程共享一个对象

在运行程序之前,可以更改“maxThreads”值以增加或减少程序中的线程数

import java.util.ArrayList;
import java.util.List;

public class ThreadSynchronization {

    public static int i = 1;
    public static final int maxThreads = 10;

    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        for (int i = 0; i < maxThreads; i++) {
            list.add(new Object());
        }
        Object currObject = list.get(maxThreads - 1);
        for (int i = 0; i < maxThreads; i++) {
            Object nextObject = list.get(i);
            RunnableClass1 a = new RunnableClass1(currObject, nextObject, i == 0 ? true : false);
            Thread th = new Thread(a);
            th.setName("Thread - " + (i + 1));
            th.start();
            currObject = list.get(i);
        }
    }

}

class RunnableClass implements Runnable {

    private Object currObject;
    private Object nextObject;
    private boolean firstThread;

    public RunnableClass(Object currObject, Object nextObject, boolean first) {
        this.currObject = currObject;
        this.nextObject = nextObject;
        this.firstThread = first;
    }

    @Override
    public void run() {
        int i = 0;
        try {
            if (firstThread) {
                Thread.sleep(5000);
                firstThread = false;
                System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
                synchronized (nextObject) {
                    nextObject.notify();
                }
            }
            while (i++ < Integer.MAX_VALUE) {
                synchronized (currObject) {
                    currObject.wait();
                }
                System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
                Thread.sleep(1000);
                synchronized (nextObject) {
                    nextObject.notify();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ThreadSynchronization类可以是 用于按顺序打印“n”个线程之间的数字。 逻辑是在每个连续线程之间创建一个公共对象,并使用“等待”、“通知”按顺序打印数字。 注意:最后一个线程将与第一个线程共享一个对象

在运行程序之前,可以更改“maxThreads”值以增加或减少程序中的线程数

import java.util.ArrayList;
import java.util.List;

public class ThreadSynchronization {

    public static int i = 1;
    public static final int maxThreads = 10;

    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        for (int i = 0; i < maxThreads; i++) {
            list.add(new Object());
        }
        Object currObject = list.get(maxThreads - 1);
        for (int i = 0; i < maxThreads; i++) {
            Object nextObject = list.get(i);
            RunnableClass1 a = new RunnableClass1(currObject, nextObject, i == 0 ? true : false);
            Thread th = new Thread(a);
            th.setName("Thread - " + (i + 1));
            th.start();
            currObject = list.get(i);
        }
    }

}

class RunnableClass implements Runnable {

    private Object currObject;
    private Object nextObject;
    private boolean firstThread;

    public RunnableClass(Object currObject, Object nextObject, boolean first) {
        this.currObject = currObject;
        this.nextObject = nextObject;
        this.firstThread = first;
    }

    @Override
    public void run() {
        int i = 0;
        try {
            if (firstThread) {
                Thread.sleep(5000);
                firstThread = false;
                System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
                synchronized (nextObject) {
                    nextObject.notify();
                }
            }
            while (i++ < Integer.MAX_VALUE) {
                synchronized (currObject) {
                    currObject.wait();
                }
                System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
                Thread.sleep(1000);
                synchronized (nextObject) {
                    nextObject.notify();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
输出:

打印值:0,按线程:线程-0打印值:1,按 线程:线程1打印值:3,按线程:线程0 打印值:2,按线程:线程-2打印值:4,按 线程:线程1打印值:6,按线程:线程0 打印值:5,按线程:线程-2打印值:7,按 线程:线程1打印值:9,按线程:线程0 打印值:8,按线程:线程2

输出:

打印值:0,按线程:线程-0打印值:1,按 线程:线程1打印值:3,按线程:线程0 打印值:2,按线程:线程-2打印值:4,按 线程:线程1打印值:6,按线程:线程0 打印值:5,按线程:线程-2打印值:7,按 线程:线程1打印值:9,按线程:线程0 打印值:8,按线程:线程2



如果不使用某种形式的同步,那么当然会发生这种情况!如果您想要串行行为,请不要使用线程。@Eyal:正如我提到的,要保持正确的序列shld,即输出shld为1,2,3,4,5,6,7,8,9。如果您不使用某种形式的同步,那么当然会发生这种情况!如果您想要串行行为,请不要使用线程。@Eyal:正如我提到的,应保持正确的顺序,即输出shld为1,2,3,4,5,6,7,8,9。我已经说过我不想使用同步!!所以没有锁意味着等待通知不在图片中。我已经声明我不想使用同步!!所以没有锁意味着等待通知不在画面中。完美。对我来说效果很好。在sysout中使用incrementAndGet有什么不同?在原始代码中,incrementAndGet被调用。然后将返回的值与输出消息的其余部分连接起来。然后只打印消息。因此,从增量到打印消息之间有很长一段时间,另一个线程会看到AtomicInteger的新值。但是,递增和获取原子不是吗?是的,它是原子的,那又怎样?它仍然在执行打印之前执行。因此其他线程可以看到新的值,并且可以在第一个线程之前打印它们的行。对我来说效果很好。在sysout中使用incrementAndGet有什么不同?在原始代码中,incrementAndGet被调用。然后将返回的值与输出消息的其余部分连接起来。然后只打印消息。因此,从增量到打印消息之间有很长一段时间,另一个线程会看到AtomicInteger的新值。但是,递增和获取原子不是吗?是的,它是原子的,那又怎样?它仍然在执行打印之前执行。因此,其他线程可以看到新的值,并可以在第一个线程之前打印它们的行。请您详细说明您的答案,并添加一点关于您提供的解决方案的说明。请您详细说明您的答案,并添加一点关于您提供的解决方案的说明,好吗?