Java 多线程 - 如何以自然顺序打印数字
Java Multithreading - How to print numbers in natural order
我在采访中了解到:
Thread-A Prints Even numbers from 0
Thread-B prints Odd numbers from 1
我想按自然顺序打印 0 1 2 3 4.... 直到 1000
我怎样才能达到。
我这样试过:
public class ThreadDemo2 {
static int aa = 0;
public static void main(String[] args) {
boolean mytime = true;
EvenThread et = new EvenThread(mytime);
OddThread ot = new OddThread(mytime);
et.start();
ot.start();
}
}
class EvenThread extends Thread {
boolean mytime;
int i = 0;
public EvenThread(boolean mytime) {
this.mytime = mytime;
}
public void run() {
//if (ThreadDemo2.aa == 0) {
for (int i = 0; i < 1000 && ThreadDemo2.aa == 0; i += 2) {
System.out.println(i);
ThreadDemo2.aa = 1;
try {
sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// }
}/* else
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
}
class OddThread extends Thread {
boolean mytime;
int i = 1;
public OddThread(boolean mytime) {
this.mytime = mytime;
}
public void run() {
//if (ThreadDemo2.aa == 1) {
for (int i = 1; i < 1000 && ThreadDemo2.aa == 1; i += 2) {
System.out.println(i);
ThreadDemo2.aa = 0;
try {
sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//ThreadDemo2.aa = 0;
//}
}
}
当你启动线程时,那时,ThreadDemo2.aa
= 0.
因此,OddThread
中的 for
循环永远不会启动。因此程序不会向前推进。
改为:
- 从两个 for 循环中删除条件
&& ThreadDemo2.aa == 0//or 1
。
- 去掉时间延迟。
- 在各自的循环中添加此行:
while(ThreadDemo2.aa == 0){}// or 1
。
此行将使 for 循环等待,直到值正确,然后循环才继续前进。这应该可以解决您的问题。
不幸的是,由于 JVM 在 2 个不同的线程上工作,因此您无法期待结果,但您可以这样做,
public class Test12 {
public static void main(String[] args) {
Thread1 t1=new Thread1();
Thread2 t2=new Thread2();
}
}
class Thread1 implements Runnable {
public Thread1() {
Thread t = new Thread();
t.start();
}
@Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
if (i % 2 == 0) {
System.out.println(i);
}
}
} catch (Exception e) {
}
}
}
class Thread2 implements Runnable {
public Thread2() {
Thread t = new Thread(this);
t.start();
}
@Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
if (i % 2 == 1) {
System.out.println(i);
}
}
} catch (Exception e) {
}
}
}
当你多次运行这个应用程序时,你会发现没有像其他 100%
那样的结果
此方法可让您执行任务。使用监视器,您将不需要添加额外的循环来确保正确的输出。
public class ThreadDemo2 {
static int aa = 0;
static Object lock = new Object();
public static void toggleThread(int threadaa) throws Exception
{
synchronized(lock)
{
if(aa == threadaa)
{
aa = (threadaa - 1) * -1;
lock.notifyAll();
lock.wait();
}
else
{
lock.wait();
}
}
}
public static void releaseThreads()
{
try
{
synchronized(lock)
{
lock.notifyAll();
}
}
catch(Exception e)
{
}
}
public static void main(String[] args) {
boolean mytime = true;
EvenThread et = new EvenThread(mytime);
OddThread ot = new OddThread(mytime);
et.start();
ot.start();
}
}
class EvenThread extends Thread {
boolean mytime;
int i = 0;
public EvenThread(boolean mytime) {
this.mytime = mytime;
}
public void run() {
//if (ThreadDemo2.aa == 0) {
for (int i = 0; i < 10; i += 2) {
try {
ThreadDemo2.toggleThread(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(i);
// }
}/* else
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
ThreadDemo2.releaseThreads();
}
}
class OddThread extends Thread {
boolean mytime;
int i = 1;
public OddThread(boolean mytime) {
this.mytime = mytime;
}
public void run() {
//if (ThreadDemo2.aa == 1) {
for (int i = 1; i < 10; i += 2) {
try {
ThreadDemo2.toggleThread(1);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(i);
}
//ThreadDemo2.aa = 0;
//}
ThreadDemo2.releaseThreads();
}
}
您练习的范围可能是使用线程锁。下面的例子使用了两个监控对象锁。每个线程基本上都在等待另一个线程完成其迭代,然后再继续前进。
public class ThreadInterleave {
public static class Even implements Runnable{
private Object even;
private Object odd;
private int count = 0;
public Even(Object even,Object odd){
this.even = even;
this.odd = odd;
}
public void run(){
while(count<1000) {
System.out.println(count);
count+=2;
synchronized (odd){
odd.notify();
}
synchronized (even){
try {
even.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static class Odd implements Runnable{
private Object even;
private Object odd;
private int count = 1;
public Odd(Object even,Object odd){
this.even = even;
this.odd = odd;
}
public void run(){
while(count<1000) {
System.out.println(count);
count+=2;
synchronized (even){
even.notify();
}
synchronized (odd){
try {
odd.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args){
final Object even = new Object();
final Object odd = new Object();
Thread tEven = new Thread(new Even(even,odd));
Thread tOdd = new Thread(new Odd(even,odd));
tEven.start();
tOdd.start();
}
}
我在采访中了解到:
Thread-A Prints Even numbers from 0
Thread-B prints Odd numbers from 1
我想按自然顺序打印 0 1 2 3 4.... 直到 1000 我怎样才能达到。
我这样试过:
public class ThreadDemo2 {
static int aa = 0;
public static void main(String[] args) {
boolean mytime = true;
EvenThread et = new EvenThread(mytime);
OddThread ot = new OddThread(mytime);
et.start();
ot.start();
}
}
class EvenThread extends Thread {
boolean mytime;
int i = 0;
public EvenThread(boolean mytime) {
this.mytime = mytime;
}
public void run() {
//if (ThreadDemo2.aa == 0) {
for (int i = 0; i < 1000 && ThreadDemo2.aa == 0; i += 2) {
System.out.println(i);
ThreadDemo2.aa = 1;
try {
sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// }
}/* else
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
}
class OddThread extends Thread {
boolean mytime;
int i = 1;
public OddThread(boolean mytime) {
this.mytime = mytime;
}
public void run() {
//if (ThreadDemo2.aa == 1) {
for (int i = 1; i < 1000 && ThreadDemo2.aa == 1; i += 2) {
System.out.println(i);
ThreadDemo2.aa = 0;
try {
sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//ThreadDemo2.aa = 0;
//}
}
}
当你启动线程时,那时,ThreadDemo2.aa
= 0.
因此,OddThread
中的 for
循环永远不会启动。因此程序不会向前推进。
改为:
- 从两个 for 循环中删除条件
&& ThreadDemo2.aa == 0//or 1
。 - 去掉时间延迟。
- 在各自的循环中添加此行:
while(ThreadDemo2.aa == 0){}// or 1
。
此行将使 for 循环等待,直到值正确,然后循环才继续前进。这应该可以解决您的问题。
不幸的是,由于 JVM 在 2 个不同的线程上工作,因此您无法期待结果,但您可以这样做,
public class Test12 {
public static void main(String[] args) {
Thread1 t1=new Thread1();
Thread2 t2=new Thread2();
}
}
class Thread1 implements Runnable {
public Thread1() {
Thread t = new Thread();
t.start();
}
@Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
if (i % 2 == 0) {
System.out.println(i);
}
}
} catch (Exception e) {
}
}
}
class Thread2 implements Runnable {
public Thread2() {
Thread t = new Thread(this);
t.start();
}
@Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
if (i % 2 == 1) {
System.out.println(i);
}
}
} catch (Exception e) {
}
}
}
当你多次运行这个应用程序时,你会发现没有像其他 100%
那样的结果此方法可让您执行任务。使用监视器,您将不需要添加额外的循环来确保正确的输出。
public class ThreadDemo2 {
static int aa = 0;
static Object lock = new Object();
public static void toggleThread(int threadaa) throws Exception
{
synchronized(lock)
{
if(aa == threadaa)
{
aa = (threadaa - 1) * -1;
lock.notifyAll();
lock.wait();
}
else
{
lock.wait();
}
}
}
public static void releaseThreads()
{
try
{
synchronized(lock)
{
lock.notifyAll();
}
}
catch(Exception e)
{
}
}
public static void main(String[] args) {
boolean mytime = true;
EvenThread et = new EvenThread(mytime);
OddThread ot = new OddThread(mytime);
et.start();
ot.start();
}
}
class EvenThread extends Thread {
boolean mytime;
int i = 0;
public EvenThread(boolean mytime) {
this.mytime = mytime;
}
public void run() {
//if (ThreadDemo2.aa == 0) {
for (int i = 0; i < 10; i += 2) {
try {
ThreadDemo2.toggleThread(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(i);
// }
}/* else
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
ThreadDemo2.releaseThreads();
}
}
class OddThread extends Thread {
boolean mytime;
int i = 1;
public OddThread(boolean mytime) {
this.mytime = mytime;
}
public void run() {
//if (ThreadDemo2.aa == 1) {
for (int i = 1; i < 10; i += 2) {
try {
ThreadDemo2.toggleThread(1);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(i);
}
//ThreadDemo2.aa = 0;
//}
ThreadDemo2.releaseThreads();
}
}
您练习的范围可能是使用线程锁。下面的例子使用了两个监控对象锁。每个线程基本上都在等待另一个线程完成其迭代,然后再继续前进。
public class ThreadInterleave {
public static class Even implements Runnable{
private Object even;
private Object odd;
private int count = 0;
public Even(Object even,Object odd){
this.even = even;
this.odd = odd;
}
public void run(){
while(count<1000) {
System.out.println(count);
count+=2;
synchronized (odd){
odd.notify();
}
synchronized (even){
try {
even.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static class Odd implements Runnable{
private Object even;
private Object odd;
private int count = 1;
public Odd(Object even,Object odd){
this.even = even;
this.odd = odd;
}
public void run(){
while(count<1000) {
System.out.println(count);
count+=2;
synchronized (even){
even.notify();
}
synchronized (odd){
try {
odd.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args){
final Object even = new Object();
final Object odd = new Object();
Thread tEven = new Thread(new Even(even,odd));
Thread tOdd = new Thread(new Odd(even,odd));
tEven.start();
tOdd.start();
}
}