线程循环运行demo
(用notify-wait实现线程通信的小demo总结)
Java在创建线程的时候,如果需要你去让一个线程循环执行10次你会怎么做?
for(int i = 0; i < 10; i++){
thread.start();
}
第一次接触线程的人可能会这么去写,但是在Java中start方法只能执行一次。如果你这么写,将会发生这种错误。
报出错误
Exception in thread "main" java.lang.IllegalThreadStateException
因为线程的状态是不可逆转的。
那么如何实现呢?
题目是:利用三个线程循环10次循环打印ABC
来看以下我摘抄的demo:
demo1
线程类print
public class Print implements Runnable{
private static int state = 0;
private int id;
private static Object lock = new Object();
public Print(int id) {
this.id = id;
}
@Override
public void run() {
synchronized(lock) {
while(state < 30) {
if(state % 3 == id) {
switch(id) {
case 0:
System.out.println("[" + Thread.currentThread().getName() + "]" + "A");
break;
case 1:
System.out.println("[" + Thread.currentThread().getName() + "]" + "B");
break;
case 2:
System.out.println("[" + Thread.currentThread().getName() + "]" + "C");
break;
default:
break;
}
state++;
lock.notifyAll();
}else {
try {
lock.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
}
}
主类:
public class Main {
public static void main(String[] args) {
Print p1 = new Print(0);
Print p2 = new Print(1);
Print p3 = new Print(2);
new Thread(p1,"p1").start();
new Thread(p2,"p2").start();
new Thread(p3,"p3").start();
while(Thread.activeCount() > 1)
;
//检查是否只有一个主线程在运行了
System.out.println("Done!");
}
}
运行结果:
[p1]A
[p2]B
[p3]C
[p1]A
[p2]B
[p3]C
[p1]A
[p2]B
[p3]C
[p1]A
[p2]B
[p3]C
[p1]A
[p2]B
[p3]C
[p1]A
[p2]B
[p3]C
[p1]A
[p2]B
[p3]C
[p1]A
[p2]B
[p3]C
[p1]A
[p2]B
[p3]C
[p1]A
[p2]B
[p3]C
Done!
第二个demo:
线程类MyThread
public class MyThread extends Thread{
private Object lock;
private String showChar;
private int showNumPosition;
private int printCount = 0;
volatile private static int addNumber = 1;
public MyThread(Object lock,String showChar,int showNumPosition) {
super();
this.lock = lock;
this.showChar = showChar;
this.showNumPosition = showNumPosition;
}
@Override
public void run() {
try {
synchronized(lock) {
while(true) {
if(addNumber % 3 == showNumPosition) {
System.out.println("ThreadName=" + Thread.currentThread().getName()
+ "runCount" + addNumber + " " + showChar);
lock.notifyAll();
addNumber++;
printCount++;
if(printCount == 10) {
break;
}
}else {
lock.wait();
}
}
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
主类:
public class Demo {
public static void main(String[] args) {
Object lock = new Object();
MyThread a = new MyThread(lock,"A",1);
MyThread b = new MyThread(lock,"B",2);
MyThread c = new MyThread(lock,"C",0);
a.start();
b.start();
c.start();
}
}
运行结果:
ThreadName=Thread-0runCount1 A
ThreadName=Thread-1runCount2 B
ThreadName=Thread-2runCount3 C
ThreadName=Thread-0runCount4 A
ThreadName=Thread-1runCount5 B
ThreadName=Thread-2runCount6 C
ThreadName=Thread-0runCount7 A
ThreadName=Thread-1runCount8 B
ThreadName=Thread-2runCount9 C
ThreadName=Thread-0runCount10 A
ThreadName=Thread-1runCount11 B
ThreadName=Thread-2runCount12 C
ThreadName=Thread-0runCount13 A
ThreadName=Thread-1runCount14 B
ThreadName=Thread-2runCount15 C
ThreadName=Thread-0runCount16 A
ThreadName=Thread-1runCount17 B
ThreadName=Thread-2runCount18 C
ThreadName=Thread-0runCount19 A
ThreadName=Thread-1runCount20 B
ThreadName=Thread-2runCount21 C
ThreadName=Thread-0runCount22 A
ThreadName=Thread-1runCount23 B
ThreadName=Thread-2runCount24 C
ThreadName=Thread-0runCount25 A
ThreadName=Thread-1runCount26 B
ThreadName=Thread-2runCount27 C
ThreadName=Thread-0runCount28 A
ThreadName=Thread-1runCount29 B
ThreadName=Thread-2runCount30 C
总结:
所以可以看到,要想实现多次运行一个线程就必须利用wait方法释放线程占用的锁,然后再用notify重新获取锁,再进行使用,做一个小demo记录方便以后的编程学习。