Multithreading 乒乓球程序Java多线程
我试图学习多线程的基本概念 为什么我的乒乓程序只打印Ping0&Pong0,为什么notify()不启动处于等待状态的乒乓线程 公共类乒乓球实现可运行{ 字符串字Multithreading 乒乓球程序Java多线程,multithreading,Multithreading,我试图学习多线程的基本概念 为什么我的乒乓程序只打印Ping0&Pong0,为什么notify()不启动处于等待状态的乒乓线程 公共类乒乓球实现可运行{ 字符串字 public PingPong(String word) { this.word = word; } public void run() { synchronized (this) { for (int i = 0; i < 10; i++) { System.out.
public PingPong(String word) {
this.word = word;
}
public void run() {
synchronized (this) {
for (int i = 0; i < 10; i++) {
System.out.println(word + i);
try {
wait();
notifyAll();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
public static void main(String[] args) {
Runnable p1 = new PingPong("ping");
Thread t1 = new Thread(p1);
t1.start();
Runnable p2 = new PingPong("pong");
Thread t2 = new Thread(p2);
t2.start();
}
}
我尝试删除wait(),它会打印乒乓球直到循环结束。但这能保证它会按顺序打印吗
为什么wait()后跟notify()不要求ping1线程开始执行
synchronized(this)
时,它们不会竞争同一个锁,因此通知这种方式不起作用。请尝试使用另一个对象作为锁String word;
Object a;
public PingPong(String word, Object a) {
this.word = word;
this.a = a;
}
public void run() {
synchronized (a) {
for (int i = 0; i < 10; i++) {
System.out.println(word + i);
try {
a.notifyAll();
a.wait();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Runnable p1 = new PingPong("ping", a);
Thread t1 = new Thread(p1);
t1.start();
Runnable p2 = new PingPong("pong", a);
Thread t2 = new Thread(p2);
t2.start();
}
字符串字;
对象a;
公共乒乓球(字符串、对象a){
这个单词=单词;
这个a=a;
}
公开募捐{
已同步(a){
对于(int i=0;i<10;i++){
系统输出打印项次(word+i);
试一试{
a、 notifyAll();
a、 等待();
}捕获(例外e){
System.out.println(e.getMessage());
}
}
}
}
公共静态void main(字符串[]args)引发InterruptedException{
对象a=新对象();
Runnable p1=新乒乓球(“ping”,a);
螺纹t1=新螺纹(p1);
t1.start();
Runnable p2=新乒乓球(“乒乓球”,a);
螺纹t2=新螺纹(p2);
t2.start();
}
synchronized(this)
时,它们不会竞争同一个锁,因此通知这种方式不起作用。请尝试使用另一个对象作为锁String word;
Object a;
public PingPong(String word, Object a) {
this.word = word;
this.a = a;
}
public void run() {
synchronized (a) {
for (int i = 0; i < 10; i++) {
System.out.println(word + i);
try {
a.notifyAll();
a.wait();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Object a = new Object();
Runnable p1 = new PingPong("ping", a);
Thread t1 = new Thread(p1);
t1.start();
Runnable p2 = new PingPong("pong", a);
Thread t2 = new Thread(p2);
t2.start();
}
字符串字;
对象a;
公共乒乓球(字符串、对象a){
这个单词=单词;
这个a=a;
}
公开募捐{
已同步(a){
对于(int i=0;i<10;i++){
系统输出打印项次(word+i);
试一试{
a、 notifyAll();
a、 等待();
}捕获(例外e){
System.out.println(e.getMessage());
}
}
}
}
公共静态void main(字符串[]args)引发InterruptedException{
对象a=新对象();
Runnable p1=新乒乓球(“ping”,a);
螺纹t1=新螺纹(p1);
t1.start();
Runnable p2=新乒乓球(“乒乓球”,a);
螺纹t2=新螺纹(p2);
t2.start();
}
下面是一个使用线程池执行器的类似解决方案:
public class PingPong implements Runnable {
String word;
Lock lock;
public PingPong(String word, Lock lock) {
this.word = word;
this.lock = lock;
}
@Override
public void run() {
while(true){
System.out.println("Received : " + word);
lock.notifyAll();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService ex = Executors.newFixedThreadPool(2);
Lock lock = new ReentrantLock();
while(true){
ex.submit(new PingPong("ping", lock));
ex.submit(new PingPong("pong", lock));
}
}
}
下面是一个使用线程池执行器的类似解决方案:
public class PingPong implements Runnable {
String word;
Lock lock;
public PingPong(String word, Lock lock) {
this.word = word;
this.lock = lock;
}
@Override
public void run() {
while(true){
System.out.println("Received : " + word);
lock.notifyAll();
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService ex = Executors.newFixedThreadPool(2);
Lock lock = new ReentrantLock();
while(true){
ex.submit(new PingPong("ping", lock));
ex.submit(new PingPong("pong", lock));
}
}
}
以下解决方案基于:
- Java内部API
- 执行令
public class Test { public static void main(String[] args) { SynchronousQueue<String> queue = new SynchronousQueue<>(); Thread ping = new Thread(new Task(queue, "ping", "ping")); ping.setName("ping thread"); ping.start(); Thread pong = new Thread(new Task(queue, "pong", "ping")); pong.setName("pong thread"); pong.start(); } private static class Task implements Runnable { private SynchronousQueue<String> queue; private String command; private String step; Task(SynchronousQueue<String> queue, String command, String step) { this.queue = queue; this.command = command; this.step = step; } @Override public void run() { try { if (command.equals(step)) { doCommandAndWaitRepeatedly(); } else { waitAndDoCommandRepeatedly(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } private void doCommandAndWaitRepeatedly() throws InterruptedException { while (true) { queue.offer(command, 1, TimeUnit.SECONDS); Thread.sleep(500); System.out.println(Thread.currentThread().getName() + ":" + queue.poll(1, TimeUnit.SECONDS)); } } private void waitAndDoCommandRepeatedly() throws InterruptedException { while (true) { System.out.println(Thread.currentThread().getName() + ":" + queue.poll(1, TimeUnit.SECONDS)); Thread.sleep(500); queue.offer(command, 1, TimeUnit.SECONDS); } } }
}公共类测试{ 公共静态void main(字符串[]args){ SynchronousQueue=新的SynchronousQueue(); 线程ping=新线程(新任务(队列,“ping”、“ping”); ping.setName(“ping线程”); ping.start(); 线程pong=新线程(新任务(队列,“pong”、“ping”); pong.setName(“pong线程”); pong.start(); } 私有静态类任务实现可运行{ 私有同步队列; 私有字符串命令; 私有字符串步; 任务(SynchronousQueue队列、字符串命令、字符串步骤){ this.queue=队列; this.command=命令; 这个步骤=步骤; } @凌驾 公开募捐{ 试一试{ if(命令等于(步骤)){ DoCommand和Wait(); }否则{ waitAndDoCommandRepeatedly(); } }捕捉(中断异常e){ Thread.currentThread().interrupt(); } } private void doCommandAndWaitRepeatedly()引发InterruptedException{ while(true){ queue.offer(命令,1,时间单位,秒); 睡眠(500); System.out.println(Thread.currentThread().getName()+“:”+queue.poll(1,TimeUnit.SECONDS)); } } private void waitAndDoCommandRepeatedly()抛出InterruptedException{ while(true){ System.out.println(Thread.currentThread().getName()+“:”+queue.poll(1,TimeUnit.SECONDS)); 睡眠(500); queue.offer(命令,1,时间单位,秒); } } }
- Java内部API
- 执行令
public class Test { public static void main(String[] args) { SynchronousQueue<String> queue = new SynchronousQueue<>(); Thread ping = new Thread(new Task(queue, "ping", "ping")); ping.setName("ping thread"); ping.start(); Thread pong = new Thread(new Task(queue, "pong", "ping")); pong.setName("pong thread"); pong.start(); } private static class Task implements Runnable { private SynchronousQueue<String> queue; private String command; private String step; Task(SynchronousQueue<String> queue, String command, String step) { this.queue = queue; this.command = command; this.step = step; } @Override public void run() { try { if (command.equals(step)) { doCommandAndWaitRepeatedly(); } else { waitAndDoCommandRepeatedly(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } private void doCommandAndWaitRepeatedly() throws InterruptedException { while (true) { queue.offer(command, 1, TimeUnit.SECONDS); Thread.sleep(500); System.out.println(Thread.currentThread().getName() + ":" + queue.poll(1, TimeUnit.SECONDS)); } } private void waitAndDoCommandRepeatedly() throws InterruptedException { while (true) { System.out.println(Thread.currentThread().getName() + ":" + queue.poll(1, TimeUnit.SECONDS)); Thread.sleep(500); queue.offer(command, 1, TimeUnit.SECONDS); } } }
公共类测试{ 公共静态void main(字符串[]args){ SynchronousQueue=新的SynchronousQueue(); 线程ping=新线程(新任务(队列,“ping”、“ping”); ping.setName(“ping线程”); ping.start(); 线程pong=新线程(新任务(队列,“pong”、“ping”); pong.setName(“pong线程”); pong.start(); } 私有静态类任务实现可运行{ 私有同步队列; 私有字符串命令; 私有字符串步; 任务(SynchronousQueue队列、字符串命令、字符串步骤){ this.queue=队列; this.command=命令; 这个步骤=步骤; } @凌驾 公开募捐{ 试一试{ if(命令等于(步骤)){ DoCommand和Wait(); }否则{ waitAndDoCommandRepeatedly(); } }捕捉(中断异常e){ Thread.currentThread().interrupt(); } } private void doCommandAndWaitRepeatedly()引发InterruptedException{ while(true){ queue.offer(命令,1,时间单位,秒); 睡眠(500); System.out.println(Thread.currentThread().getNam
- 以下解决方案基于: