在java中使用10个线程打印1到100
我是多线程新手,我有一个问题要在Java中使用10个线程打印1到100个线程,并带有以下约束在java中使用10个线程打印1到100,java,multithreading,Java,Multithreading,我是多线程新手,我有一个问题要在Java中使用10个线程打印1到100个线程,并带有以下约束 线程t1应打印: 1、11、21、31。。。91 t2应打印: 2、12、22、32。。。92 同样地 t10应打印: 10、20、30。。。一百 最终输出应该是 1 2 3。。一百 我已经尝试过了,但它在所有10个线程中都抛出了以下异常: java.lang.IllegalMonitorStateException at java.lang.Object.wait(Native Metho
t1
应打印:
1、11、21、31。。。91
t2
应打印:
2、12、22、32。。。92
同样地
t10
应打印:
10、20、30。。。一百
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at thread.run(MyThread.java:58)
at java.lang.Thread.run(Unknown Source)
请告诉我如何解决这个问题
public class MyThread {
/**
* @param args
*/
public static void main(String[] args) {
thread.setSequence();
for(int i = 1; i <= 10; i++) {
Thread t = new Thread(new thread(i));
t.setName(i + "");
t.start();
}
}
}
class thread implements Runnable {
private static HashMap< String, String> sequence = new HashMap<String, String>();
public static final Object lock = new Object();
public static String turn = "1";
private int startValue = 0;
private AtomicInteger counter = new AtomicInteger(1);
public thread(int startValue){
this.startValue = startValue;
}
@Override
public void run() {
while (!counter.equals(10)){
synchronized (lock) {
if(Thread.currentThread().getName().equals(turn)){
System.out.print(startValue + " ");
startValue += 10;
counter.incrementAndGet();
turn = getNextTurn(turn);
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
}
}
}
public static void setSequence(){
for (int i = 1; i <= 10; i++)
if (i == 10)
sequence.put(i + "", 1 + "");
else
sequence.put(i + "", (i + 1) + "");
}
public static String getNextTurn(String currentTurn){
return sequence.get(currentTurn);
}
}
公共类读取{
/**
*@param args
*/
公共静态void main(字符串[]args){
thread.setSequence();
for(int i=1;i sequence=new HashMap();
公共静态最终对象锁=新对象();
公共静态字符串turn=“1”;
私有int startValue=0;
私有AtomicInteger计数器=新的AtomicInteger(1);
公共线程(int startValue){
this.startValue=startValue;
}
@凌驾
公开募捐{
而(!counter.equals(10)){
已同步(锁定){
如果(Thread.currentThread().getName().equals(turn)){
系统输出打印(startValue+“”);
起始值+=10;
counter.incrementAndGet();
turn=getNextTurn(turn);
试一试{
这个。等等();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
否则{
试一试{
这个。等等();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
this.notifyAll();
}
}
}
公共静态void setSequence(){
对于(inti=1;i来说,最简单的方法是为所有这些对象保留公共资源。
持有一个列表,每个线程都会插入到列表中,最后你可以排序和打印。。
如果你想让他们在你的订单上做这件事,这将不是很有效,因为你不需要10个线程来做这件事
这样会更快,并且会使用10个线程来完成一些工作,但是当每个人都完成时,您仍然需要做一些工作公共类PrintNumbersbyThreads实现Runnable{
public class PrintNumbersbyThreads implements Runnable {
private int i;
public PrintNumbersbyThreads(int i) {
this.i = i;
}
public static void main(String[] args) {
PrintNumbersbyThreads p = new PrintNumbersbyThreads(1);
PrintNumbersbyThreads p2 = new PrintNumbersbyThreads(2);
PrintNumbersbyThreads p3 = new PrintNumbersbyThreads(3);
Thread t1 = new Thread(p, "t1");
Thread t2 = new Thread(p2, "t2");
Thread t3 = new Thread(p3, "t3");
t1.start();
try {
t1.join();
t2.start();
t2.join();
t3.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
System.out.println("\n" + Thread.currentThread().getName() + " prints ");
for (int j = 0; j < 10; j++) {
System.out.print(i + " ");
i = i + 10;
}
}
}
私人互联网i;
公共PrintNumbersbyThreads(int i){
这个。i=i;
}
公共静态void main(字符串[]args){
PrintNumbersbyThreads p=新的PrintNumbersbyThreads(1);
PrintNumbersbyThreads p2=新的PrintNumbersbyThreads(2);
PrintNumbersbyThreads p3=新的PrintNumbersbyThreads(3);
螺纹t1=新螺纹(p,“t1”);
螺纹t2=新螺纹(p2,“t2”);
螺纹t3=新螺纹(p3,“t3”);
t1.start();
试一试{
t1.join();
t2.start();
t2.连接();
t3.start();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
@凌驾
公开募捐{
System.out.println(“\n”+线程.currentThread().getName()+打印”);
对于(int j=0;j<10;j++){
系统输出打印(i+“”);
i=i+10;
}
}
}
编写了3个线程的示例代码,输出为
t1
打印:
11121314161718191
t2
打印:
2 12 22 32 42 52 62 82 92
t3
打印:
3132333435363738393
希望这就是您正在寻找的吗?最简单的方法是使用一个可变变量,每个线程从中读入并根据其轮次进行更新,否则它只会等待轮到自己。当计数器等于100
时,您可以通过中断外部循环来停止所有线程的运行
class MyRunnable implements Runnable {
private static final int LIMIT = 20;
private static volatile int counter = 0;
private int id;
public MyRunnable(int id) {
this.id = id;
}
@Override
public void run() {
outer:
while(counter < LIMIT) {
while (counter % NB_THREADS != id) {
if(counter == LIMIT) break outer;
}
System.out.println("Thread "+Thread.currentThread().getName()+ " printed " + counter);
counter += 1;
}
}
}
当然,这是多线程的一个非常糟糕的用法,因为每个线程都会等待轮到它打印并递增计数器
当线程可以在相对较长的时间内独立于另一个线程工作时,多线程就可以很好地工作,如果需要的话,还可以偶尔碰头比较或合并它们的结果
例如,在fork-join模型中,每个线程独立地执行其任务,然后合并它们的结果以生成最终结果,例如在合并排序中。但这假设任务可以轻松地并行到独立的子任务中,这里不是这种情况,因为您的最终输出应该是连续的数字
所以在这里,一个简单的循环会更有效,但我可以理解它是为了学习的目的。错误是由于调用wait
而不是在正确的对象上引发的。wait()
应该在获取锁的对象上调用,该对象由synchronized
关键字暗示。希望这有帮助=)我花了一个小时做这件事
package com.xxxx.simpleapp;
import java.util.ArrayList;
import java.util.List;
public class TenThreads {
public int currentTaskValue = 1;
public static void main(String[] args) {
TenThreads monitor = new TenThreads();
List<ModThread> list = new ArrayList();
for (int i = 0; i < 10; i++) {
ModThread modThread = new ModThread(i, monitor);
list.add(modThread);
}
for (ModThread a : list) {
a.start();
}
}
}
class ModThread extends Thread {
private int modValue;
private TenThreads monitor;
public ModThread(int modValue, TenThreads monitor) {
this.modValue = modValue;
this.monitor = monitor;
}
@Override
public void run() {
synchronized (monitor) {
try {
while (true) {
while (monitor.currentTaskValue % 10 != modValue) {
monitor.wait();
}
if (monitor.currentTaskValue == 101) {
break;
}
System.out.println(Thread.currentThread().getName() + " : "
+ monitor.currentTaskValue + " ,");
monitor.currentTaskValue = monitor.currentTaskValue + 1;
monitor.notifyAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
为了让您弄清楚,特意省略了文档,还有一些小错误!我已经编写了一个通用代码,它将记录您要打印的位置和要使用的线程数
public class ThreadedPrinting {
private Object locks[];
private static class Printer extends Thread {
int curVal;
int endVal;
Object myLock;
Object nextLock;
int step;
public Printer(int startFrom, int endVal, int step, Object myLock, Object nextLock){
this.curVal = startFrom;
this.endVal = endVal;
this.step = step;
this.myLock = myLock;
this.nextLock = nextLock;
this.step = step;
}
@Override
public void run(){
synchronized(myLock) {
while (curVal <= endVal) {
try {
myLock.wait();
System.out.println(curVal);
curVal += step;
}
catch(InterruptedException e) {}
synchronized(nextLock) {
nextLock.notify();
}
}
}
synchronized(nextLock) {
nextLock.notify(); /// this ensures all worker threads exiting at the end
}
}
} // Printer
public ThreadedPrinting(int maxNum, int threads) {
locks = new Object[threads];
int i;
for(i = 0; i < threads; ++i) locks[i] = new Object();
for(i = 0; i < threads -1 ; ++i) {
Printer curPrinter = new Printer(i, maxNum, threads, locks[i], locks[i+1]);
curPrinter.start();
}
Printer lastPrinter = new Printer(i, maxNum, threads, locks[threads - 1], locks[0]);
lastPrinter.start();
}
public void start() {
synchronized (locks[0]) {
locks[0].notify();
}
}
public static void main(String[] args) {
ThreadedPrinting printer = new ThreadedPrinting(1000,7);
printer.start();
}
}
公共类线程打印{
私有对象锁[];
私有静态类打印机扩展线程{
int曲线;
内端点;
对象myLock;
对象nextLock;
整数步;
公用打印机(int startFrom、int endVal、int step、对象myLock、对象nextLock){
this.curVal=startFrom;
this.endVal=endVal;
这个步骤=步骤;
this.myLock=myLock;
this.nextLock=nextLock;
这个步骤=步骤;
}
@凌驾
公开募捐{
已同步(myLock){
虽然(curVal嗯,我没有代码…但是透视图似乎是
有100项任务需要完成
Thread-1 : 1 ,
Thread-2 : 2 ,
Thread-3 : 3 ,
Thread-4 : 4 ,
Thread-5 : 5 ,
Thread-6 : 6 ,
Thread-7 : 7 ,
Thread-8 : 8 ,
Thread-9 : 9 ,
......
.....
...
Thread-4 : 94 ,
Thread-5 : 95 ,
Thread-6 : 96 ,
Thread-7 : 97 ,
Thread-8 : 98 ,
Thread-9 : 99 ,
Thread-0 : 100 ,
public class ThreadedPrinting {
private Object locks[];
private static class Printer extends Thread {
int curVal;
int endVal;
Object myLock;
Object nextLock;
int step;
public Printer(int startFrom, int endVal, int step, Object myLock, Object nextLock){
this.curVal = startFrom;
this.endVal = endVal;
this.step = step;
this.myLock = myLock;
this.nextLock = nextLock;
this.step = step;
}
@Override
public void run(){
synchronized(myLock) {
while (curVal <= endVal) {
try {
myLock.wait();
System.out.println(curVal);
curVal += step;
}
catch(InterruptedException e) {}
synchronized(nextLock) {
nextLock.notify();
}
}
}
synchronized(nextLock) {
nextLock.notify(); /// this ensures all worker threads exiting at the end
}
}
} // Printer
public ThreadedPrinting(int maxNum, int threads) {
locks = new Object[threads];
int i;
for(i = 0; i < threads; ++i) locks[i] = new Object();
for(i = 0; i < threads -1 ; ++i) {
Printer curPrinter = new Printer(i, maxNum, threads, locks[i], locks[i+1]);
curPrinter.start();
}
Printer lastPrinter = new Printer(i, maxNum, threads, locks[threads - 1], locks[0]);
lastPrinter.start();
}
public void start() {
synchronized (locks[0]) {
locks[0].notify();
}
}
public static void main(String[] args) {
ThreadedPrinting printer = new ThreadedPrinting(1000,7);
printer.start();
}
}
public class BigSequence {
public static void main(String[] args) {
BigPrintNum p = new BigPrintNum();
int max = 20;
int no_threads = 11;
for(int i=0;i<no_threads;i++){
boolean b[] = new boolean[no_threads];
b[i] = true;
Thread t = new Thread(new BigPrint(p, max, b,no_threads));
t.start();
}
}
}
class BigPrint implements Runnable {
int num=0;
BigPrintNum p;
int max;
int no_threads;
boolean b[];
public BigPrint(BigPrintNum p,int max,boolean b[],int no_threads){
this.p = p;
this.max = max;
this.b = b;
this.no_threads = no_threads;
}
@Override
public void run() {
int n = 0;
for(int i=0;i<no_threads;i++){
if(b[i] == true){
n = i;
num = i;
}
}
while(num<=max){
p.print(num, n, no_threads);
num += no_threads;
}
}
}
class BigPrintNum {
int turn = 0;
public synchronized void print(int n,int i,int no_threads){
while(this.turn != i){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println(i + "th seq = " + n);
this.turn = (i+1)%no_threads;
notifyAll();
}
}
public class ThreadSequence
{
public static int totalThread;
public static void main(String[] args)
{
MyLock myLock = new MyLock();
totalThread = 10;
for(int i=1;i<=totalThread;i++)
{
MyThread myThread = new MyThread(i,myLock);
myThread.start();
}
}
}
class MyLock
{
public int counter = 0;
}
class MyThread extends Thread{
public MyLock lock;
public int no;
public MyThread(int no,MyLock lock)
{
super("My Thread No "+no);
this.no = no;
this.lock = lock;
}
public void run()
{
synchronized (lock)
{
while(true)
{
while(lock.counter%ThreadSequence.totalThread !=(this.no-1))
{
try
{
if(lock.counter > 99)
{
break;
}
lock.wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
if(lock.counter > 99)
{
break;
}
System.out.println("Current Thread "+Thread.currentThread().currentThread()+" --- Current Count "+(lock.counter+1));
lock.counter = lock.counter +1 ;
lock.notifyAll();
}
}
}
}
public class MyThread extends Thread{
//define the Total No.Of Threads needed
public static final int TOTAL_THREADS = 10;
public final static Object obj = new Object();
int threadNo;
static volatile int counter = 1;
public MyThread(int threadNo){
this.threadNo= threadNo;
}
@Override
public void run(){
//in a synchronized block to acquire lock
synchronized (obj) {
while(counter<=100){
/*
* counter==threadNo => To print the initial numbers till TOTAL_THREADS
* counter%TOTAL_THREADS == threadNo => e.g 11%10 = 1 -> 1 will print this, 12%10 = 2 ..
* (counter%TOTAL_THREADS == 0) && (TOTAL_THREADS == threadNo) => 10%10 will be 0,
* and this must be printed by 10 th thread only, ie the highest thread.
*/
if(counter == threadNo || (counter%TOTAL_THREADS == threadNo) ||
((counter%TOTAL_THREADS == 0) && (TOTAL_THREADS == threadNo))){
//Display the output as desired
System.out.println(this.threadNo+" printing"+" "+counter++);
//notify
obj.notifyAll();
}else{
//current thread not eligible for printing the current counter value, so wait till its notified
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main (String args[]) {
/*
* Creating as many threads as needed.
*/
for(int i = 1; i<=TOTAL_THREADS;i++){
MyThread th = new MyThread(i);
th.start();
}
}
private final int index;
private final AtomicInteger atomicInteger;
private final CyclicBarrier cyclicBarrier;
public class PrintSequence {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
final AtomicInteger atomicInteger = new AtomicInteger(1);
final CyclicBarrier cyclicBarrier = new CyclicBarrier(10, ()-> {
System.out.println("a cycle done");
});
IntStream.rangeClosed(0, 9)
.boxed()
.map(i -> new PrintSequenceTask(i, atomicInteger, cyclicBarrier))
.map(p -> executorService.submit(p))
.collect(Collectors.toList());
executorService.shutdown();
}
}
class PrintSequenceTask implements Runnable {
private final int index;
private final AtomicInteger atomicInteger;
private final CyclicBarrier cyclicBarrier;
PrintSequenceTask(int index, AtomicInteger atomicInteger, CyclicBarrier cyclicBarrier) {
this.index = index;
this.atomicInteger = atomicInteger;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run(){
for(int i=1; i<10;i++){
while (((atomicInteger.get()-index-1)%10 != 0)){}
System.out.println(Thread.currentThread().getName()+" "+(atomicInteger.get()));
atomicInteger.getAndIncrement();
await();
}
}
public void await(){
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}