java 在java中使用两个线程多次打印“Hello”和“world”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16963405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Printing "Hello" and "world" multiple times using two threads in java
提问by Anushree Acharjee
Assume that one thread prints "Hello" and another prints "World". I have done it successfully for one time, as follows: package threading;
假设一个线程打印“Hello”,另一个打印“World”。我曾经做过一次成功,如下:打包线程;
public class InterThread {
public static void main(String[] args) {
MyThread mt=new MyThread();
mt.start();
synchronized(mt){
System.out.println("Hello");
try {
mt.wait();
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyThread extends Thread{
public void run(){
synchronized(this){
System.out.println("World!");
notify();
}
}
}
How do I do it for multiple time printing, say for 5 times? I tried putting for loop around the synchronized block, but of no use.
我如何进行多次打印,比如 5 次?我尝试在同步块周围放置 for 循环,但没有用。
采纳答案by harish bhatt
public class ThreadSeq {
Object hello = new Object();
Object world = new Object();
public static void main(String[] args) throws InterruptedException {
for(int i=0; i<6;i++){
Runnable helloTask = new Runnable(){
@Override
public void run(){
new ThreadSeq().printHello();
}
};
Runnable worldTask = new Runnable(){
@Override
public void run(){
new ThreadSeq().printWorld();
}
};
Thread t1 = new Thread(helloTask);
Thread t2 = new Thread(worldTask);
t1.start();
t1.join();
t2.start();
t2.join();
}
}
public void printHello(){
synchronized (hello) {
System.out.println("Hello");
}
}
public void printWorld(){
synchronized (world) {
System.out.println("World");
}
}
}
回答by inquisitive
Here being two interdependent threads, we need two synchronizing objects. they could be one of many things. one integer, another object; one Boolean another object; both object; both semaphores and so on. the synchronization technique could be either Monitor or Semaphore any way you like, but they have to be two.
这是两个相互依赖的线程,我们需要两个同步对象。它们可能是众多事物之一。一个整数,另一个对象;一个布尔另一个对象;两个对象;信号量等等。同步技术可以是 Monitor 或 Semaphore 任何你喜欢的方式,但它们必须是两个。
I have modified your code to use semaphore instead of Monitor. The Semaphore works more transparently. You can see the acquire and release happening. Monitors are even higher constructs. Hence Synchronized works under the hood.
我已修改您的代码以使用信号量而不是监视器。信号量的工作更加透明。您可以看到发生的获取和释放。监视器是更高的结构。因此,同步在幕后工作。
If you are comfortable with the following code, then you can convert it to use Monitors instead.
如果您对以下代码感到满意,则可以将其转换为使用 Monitors。
import java.util.concurrent.Semaphore;
public class MainClass {
static Semaphore hello = new Semaphore(1);
static Semaphore world = new Semaphore(0);
public static void main(String[] args) throws InterruptedException {
MyThread mt=new MyThread();
mt.hello = hello;
mt.world = world;
mt.start();
for (int i=0; i<5; i++) {
hello.acquire(); //wait for it
System.out.println("Hello");
world.release(); //go say world
}
}
}
class MyThread extends Thread{
Semaphore hello, world;
public void run(){
try {
for(int i = 0; i<5; i++) {
world.acquire(); // wait-for it
System.out.println(" World!");
hello.release(); // go say hello
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
回答by UmNyobe
The goal here is to synchronize threads so that when one is done it notify the other. If I have to make it, it would be 2 threads executing the same code with different data. Each thread has its own data ("Hello"
and true
to T1, "World"
and false
to t2), and share a variable turn
plus a separate lock object.
这里的目标是同步线程,以便在一个线程完成时通知另一个线程。如果我必须这样做,它将是 2 个线程使用不同的数据执行相同的代码。每个线程都有自己的数据("Hello"
和true
到 T1,"World"
和false
到 t2),并共享一个变量turn
和一个单独的锁对象。
while(/* I need to play*/){
synchronized(lock){
if(turn == myturn){
System.out.println(mymessage);
turn = !turn; //switch turns
lock.signal();
}
else{
lock.wait();
}
}
}
回答by selig
Before you start trying to get it to work five times you need to make sure it works once!
在你开始尝试让它工作五次之前,你需要确保它工作一次!
Your code is not guaranteed to always print Hello World! - the main thread could be interrupted before taking the lock of mt (note that locking on thread objects is generally not a good idea).
您的代码不能保证总是打印 Hello World!- 主线程可能会在获取 mt 锁定之前被中断(注意锁定线程对象通常不是一个好主意)。
MyThread mt=new MyThread();
mt.start();
\ interrupted here
synchronized(mt){
...
One approach, that will generalise to doing this many times, is to use an atomic boolean
一种可以推广到多次执行此操作的方法是使用原子布尔值
import java.util.concurrent.atomic.AtomicBoolean;
public class InterThread {
public static void main(String[] args) {
int sayThisManyTimes = 5;
AtomicBoolean saidHello = new AtomicBoolean(false);
MyThread mt=new MyThread(sayThisManyTimes,saidHello);
mt.start();
for(int i=0;i<sayThisManyTimes;i++){
while(saidHello.get()){} // spin doing nothing!
System.out.println("Hello ");
saidHello.set(true);
}
}
}
class MyThread extends Thread{
private final int sayThisManyTimes;
private final AtomicBoolean saidHello;
public MyThread(int say, AtomicBoolean said){
super("MyThread");
sayThisManyTimes = say;
saidHello = said;
}
public void run(){
for(int i=0;i<sayThisManyTimes;i++){
while(!saidHello.get()){} // spin doing nothing!
System.out.println("World!");
saidHello.set(false);
}
}
}
回答by rcreddy
This is in C:
这是在 C 中:
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t hello_lock, world_lock;
void printhello()
{
while(1) {
pthread_mutex_lock(&hello_lock);
printf("Hello ");
pthread_mutex_unlock(&world_lock);
}
}
void printworld()
{
while(1) {
pthread_mutex_lock(&world_lock);
printf("World ");
pthread_mutex_unlock(&hello_lock);
}
}
int main()
{
pthread_t helloThread, worldThread;
pthread_create(&helloThread,NULL,(void *)printhello,NULL);
pthread_create(&helloThread,NULL,(void *)printhello,NULL);
pthread_join(helloThread);
pthread_join(worldThread);
return 0;
}
回答by lalit lakhchaura
There are two thread and both has its own data ("Hello" and true to ht, "World" and false to wt), and share a variable objturn.
有两个线程,它们都有自己的数据(“Hello”和 true 到 ht,“World”和 false 到 wt),并共享一个变量 objturn。
public class HelloWorldBy2Thread {
public static void main(String[] args) {
PrintHelloWorld hw = new PrintHelloWorld();
HelloThread ht = new HelloThread(hw);
WorldThread wt = new WorldThread(hw);
ht.start();
wt.start();
}
}
public class HelloThread extends Thread {
private PrintHelloWorld phw;
private String hello;
public HelloThread(PrintHelloWorld hw) {
phw = hw;
hello = "Hello";
}
@Override
public void run(){
for(int i=0;i<10;i++)
phw.print(hello,true);
}
}
public class WorldThread extends Thread {
private PrintHelloWorld phw;
private String world;
public WorldThread(PrintHelloWorld hw) {
phw = hw;
world = "World";
}
@Override
public void run(){
for(int i=0;i<10;i++)
phw.print(world,false);
}
}
public class PrintHelloWorld {
private boolean objturn=true;
public synchronized void print(String str, boolean thturn){
while(objturn != thturn){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(str+" ");
objturn = ! thturn;
notify();
}
}
回答by Rahul Ghadage
In simple way we can do this using wait()
and notify()
without creating any extra object.
在简单的方法,我们可以用这个做wait()
并notify()
不会产生任何额外的对象。
public class MainHelloWorldThread {
public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorld();
Thread t1 = new Thread(() -> {
try {
helloWorld.printHello();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
helloWorld.printWorld();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// printHello() will be called first
t1.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}
class HelloWorld {
public void printHello() throws InterruptedException {
synchronized (this) {
// Infinite loop
while (true) {
// Sleep for 500ms
Thread.sleep(500);
System.out.print("Hello ");
wait();
// This thread will wait to call notify() from printWorld()
notify();
// This notify() will release lock on printWorld() thread
}
}
}
public void printWorld() throws InterruptedException {
synchronized (this) {
// Infinite loop
while (true) {
// Sleep for 100ms
Thread.sleep(100);
System.out.println("World");
notify();
// This notify() will release lock on printHello() thread
wait();
// This thread will wait to call notify() from printHello()
}
}
}
}