Java 线程:如何使用两个线程一次一个地打印字母和数字
Java Threads: How to print alphabets and numbers using two threads one at a time
我正在尝试使用 java 中的线程。虽然我知道线程输出是不可预测的,但是想知道是否有办法做到这一点。
我必须实现两个线程,一个打印字母(a,b,c...z)
,另一个打印数字(1,2,3....26)
。必须以输出应为 a,1,b,2,c,3,d,4......z,26
的方式实现它。下面是我的代码,但它没有提供所需的输出。
public class ThreadsExample {
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
System.out.print(i+",");
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
System.out.print(i+",");
}
}
}
我应该在代码中进行哪些调整才能获得所需的输出? synchronization
在这里有什么帮助?或者在使用线程时真的有可能吗?
PS:这不是作业或练习。自学。
线程的全部思想:它代表一个"stream of activity"独立于其他线程执行代码。
在您的情况下,您希望这两个线程进入 "lockstep"。线程A做一步,然后线程B,然后A,然后B.
为了到达那里,两个线程需要一些东西 "synchronize" - 换句话说:A 在完成其步骤后向 B 发送 信号 - B 必须等待该信号。然后 B 做它的事情,向 A 发出信号,...
对于初学者来说,一个简单的布尔值就可以了。一个线程将其设置为 true,另一个线程将其设置为 false(以指示它何时完成了它的步骤)。然后线程等待布尔值再次切换。
因为你打算学习东西,我会从那里开始试验。如果你想少走弯路,看看here for example. This或许也有帮助。
您的线程同时 运行。但不是你想要的方式,如上所述。您将看到来自线程 1 的数据块,然后是来自线程 2 的数据块;这是因为线程调度。线程 1 只是在线程 2 之前排队其输出。
为了检验这个理论,将你的输出增加到 1000 条记录,例如字母表和 26 个数字没有那么大,看不到这个。
这样做,您将看到这些 'blocks' 数据。有一种方法可以执行您提到的操作,但不建议这样做,因为这并不是在演示线程实际如何工作,而是您强迫它以这种方式工作。
有可能。你需要同步好。
接近伪代码
查询一些(同步的)状态
state 将判断是否允许使用 nums 或 chars
如果状态允许 char 并且调用者将放入 char,现在就执行并更改状态并唤醒等待线程
如果没有,请等待
如果状态允许数字并且调用者将输入数字,请立即执行并更改状态并唤醒等待线程
如果没有,请等待
Java代码
public class ThreadsExample {
public static ThreadsExample output = new ThreadsExample ();
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
private Object syncher = new Object (); // we use an explicit synch Object, you could use annotation on methods, too. like ABHISHEK did.
// explicit allows to deal with more complex situations, especially you could have more the one locking Object
private int state = 0; // 0 allows chars, 1 allows ints
public void print (char pChar) {
synchronized (syncher) { // prevent the other print to access state
while (true) {
if (state == 0) { // char are allowed
System.out.print(pChar + ","); // print it
state = 1; // now allow ints
syncher.notify(); // wake up all waiting threads
return;
} else { // not allowed for now
try {
syncher.wait(); // wait on wake up
} catch (InterruptedException e) {
}
}
}
}
}
public void print (int pInt) {
synchronized (syncher) {
while (true) {
if (state == 1) {
System.out.print(pInt + ",");
state = 0;
syncher.notify();
return;
} else {
try {
syncher.wait();
} catch (InterruptedException e) {
}
}
}
}
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
ThreadsExample.output.print(i);
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
ThreadsExample.output.print(i);
}
}
}
输出
a,1,b,2,c,3,d,4,e,5,f,6,g,7,h,8,i,9,j,10,k,11,l ,12,m,13,n,14,o,15,p,16,q,17,r,18,s,19,t,20,u,21,v,22,w,23,x,24 ,y,25,z,26,
这是代码::
您需要创建 2 个线程并正确实现等待和通知方法您也可以参考“Create two threads, one display odd & other even numbers”作为您的答案。
public class ThreadClass {
volatile int i = 1;
volatile Character c = 'a';
volatile boolean state = true;
synchronized public void printAlphabet() {
try {
while (!state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " +c);
state = false;
c++;
notifyAll();
}
synchronized public void printNumbers() {
try {
while (state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
state = true;
i++;
notifyAll();
}
public static void main(String[] args) {
ThreadClass threadClass = new ThreadClass();
Thread t1 = new Thread() {
int k = 0;
@Override
public void run() {
while (k < 26) {
threadClass.printAlphabet();
k++;
}
}
};
t1.setName("Thread1");
Thread t2 = new Thread() {
int j = 0;
@Override
public void run() {
while (j < 26) {
threadClass.printNumbers();
j++;
}
}
};
t2.setName("Thread2");
t1.start();
t2.start();
}
}
代码较少:
class MyRunnable implements Runnable {
private static int n = 1;
private static char c = 'a';
public void run() {
for (int i = 1; i <= 26; i++) {
synchronized (this) {
try {
notifyAll();
if (Thread.currentThread().getName().equals("A")) {
System.out.print(c + ",");
c++;
} else {
System.out.print(n + ",");
n++;
}
if (i != 26) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintAlphabetNumberJob {
public static void main(String[] args) throws InterruptedException {
MyRunnable r = new MyRunnable();
Thread tAlphabet = new Thread(r, "A");
Thread tNumber = new Thread(r, "N");
tAlphabet.start();
Thread.sleep(100);
tNumber.start();
}
}
我正在尝试使用 java 中的线程。虽然我知道线程输出是不可预测的,但是想知道是否有办法做到这一点。
我必须实现两个线程,一个打印字母(a,b,c...z)
,另一个打印数字(1,2,3....26)
。必须以输出应为 a,1,b,2,c,3,d,4......z,26
的方式实现它。下面是我的代码,但它没有提供所需的输出。
public class ThreadsExample {
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
System.out.print(i+",");
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
System.out.print(i+",");
}
}
}
我应该在代码中进行哪些调整才能获得所需的输出? synchronization
在这里有什么帮助?或者在使用线程时真的有可能吗?
PS:这不是作业或练习。自学。
线程的全部思想:它代表一个"stream of activity"独立于其他线程执行代码。
在您的情况下,您希望这两个线程进入 "lockstep"。线程A做一步,然后线程B,然后A,然后B.
为了到达那里,两个线程需要一些东西 "synchronize" - 换句话说:A 在完成其步骤后向 B 发送 信号 - B 必须等待该信号。然后 B 做它的事情,向 A 发出信号,...
对于初学者来说,一个简单的布尔值就可以了。一个线程将其设置为 true,另一个线程将其设置为 false(以指示它何时完成了它的步骤)。然后线程等待布尔值再次切换。
因为你打算学习东西,我会从那里开始试验。如果你想少走弯路,看看here for example. This或许也有帮助。
您的线程同时 运行。但不是你想要的方式,如上所述。您将看到来自线程 1 的数据块,然后是来自线程 2 的数据块;这是因为线程调度。线程 1 只是在线程 2 之前排队其输出。
为了检验这个理论,将你的输出增加到 1000 条记录,例如字母表和 26 个数字没有那么大,看不到这个。
这样做,您将看到这些 'blocks' 数据。有一种方法可以执行您提到的操作,但不建议这样做,因为这并不是在演示线程实际如何工作,而是您强迫它以这种方式工作。
有可能。你需要同步好。
接近伪代码
查询一些(同步的)状态 state 将判断是否允许使用 nums 或 chars
如果状态允许 char 并且调用者将放入 char,现在就执行并更改状态并唤醒等待线程
如果没有,请等待
如果状态允许数字并且调用者将输入数字,请立即执行并更改状态并唤醒等待线程
如果没有,请等待
Java代码
public class ThreadsExample {
public static ThreadsExample output = new ThreadsExample ();
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
private Object syncher = new Object (); // we use an explicit synch Object, you could use annotation on methods, too. like ABHISHEK did.
// explicit allows to deal with more complex situations, especially you could have more the one locking Object
private int state = 0; // 0 allows chars, 1 allows ints
public void print (char pChar) {
synchronized (syncher) { // prevent the other print to access state
while (true) {
if (state == 0) { // char are allowed
System.out.print(pChar + ","); // print it
state = 1; // now allow ints
syncher.notify(); // wake up all waiting threads
return;
} else { // not allowed for now
try {
syncher.wait(); // wait on wake up
} catch (InterruptedException e) {
}
}
}
}
}
public void print (int pInt) {
synchronized (syncher) {
while (true) {
if (state == 1) {
System.out.print(pInt + ",");
state = 0;
syncher.notify();
return;
} else {
try {
syncher.wait();
} catch (InterruptedException e) {
}
}
}
}
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
ThreadsExample.output.print(i);
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
ThreadsExample.output.print(i);
}
}
}
输出
a,1,b,2,c,3,d,4,e,5,f,6,g,7,h,8,i,9,j,10,k,11,l ,12,m,13,n,14,o,15,p,16,q,17,r,18,s,19,t,20,u,21,v,22,w,23,x,24 ,y,25,z,26,
这是代码:: 您需要创建 2 个线程并正确实现等待和通知方法您也可以参考“Create two threads, one display odd & other even numbers”作为您的答案。
public class ThreadClass {
volatile int i = 1;
volatile Character c = 'a';
volatile boolean state = true;
synchronized public void printAlphabet() {
try {
while (!state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " +c);
state = false;
c++;
notifyAll();
}
synchronized public void printNumbers() {
try {
while (state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
state = true;
i++;
notifyAll();
}
public static void main(String[] args) {
ThreadClass threadClass = new ThreadClass();
Thread t1 = new Thread() {
int k = 0;
@Override
public void run() {
while (k < 26) {
threadClass.printAlphabet();
k++;
}
}
};
t1.setName("Thread1");
Thread t2 = new Thread() {
int j = 0;
@Override
public void run() {
while (j < 26) {
threadClass.printNumbers();
j++;
}
}
};
t2.setName("Thread2");
t1.start();
t2.start();
}
}
代码较少:
class MyRunnable implements Runnable {
private static int n = 1;
private static char c = 'a';
public void run() {
for (int i = 1; i <= 26; i++) {
synchronized (this) {
try {
notifyAll();
if (Thread.currentThread().getName().equals("A")) {
System.out.print(c + ",");
c++;
} else {
System.out.print(n + ",");
n++;
}
if (i != 26) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintAlphabetNumberJob {
public static void main(String[] args) throws InterruptedException {
MyRunnable r = new MyRunnable();
Thread tAlphabet = new Thread(r, "A");
Thread tNumber = new Thread(r, "N");
tAlphabet.start();
Thread.sleep(100);
tNumber.start();
}
}