n******1 发帖数: 3756 | 1 自己练习写了一个多线程读一个字符串,但是没法退出,想请教两个问题
1.这种写法是我自己想出来,有没有更优雅一点的方法呢
2.线程间应该怎么通知结束信号然后退出的?
感觉多线程难用的原因因为需要全部理解才能用好,一个地方没理解好,就用不好
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
class Reader implements Runnable {
private int id;
private String[] queue;
private Object lock;
private volatile AtomicInteger index;
private int threads;
private volatile boolean done = false;
public Reader(int id, String[] queue, Object lock, AtomicInteger index,
int threads, Boolean done) {
this.id = id;
this.queue = queue;
this.lock = lock;
this.index = index;
this.threads = threads;
this.done = done;
}
public void run() {
while (!done) {
synchronized (lock) {
while (index.get() % threads != id)
try {
lock.wait();
} catch (Exception e) {
}
System.out.println("The id" + id + ": " + queue[index.get()]
);
if (index.incrementAndGet() == queue.length) {
done = true;
}
lock.notifyAll();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class MultiReading {
public static void main(String[] args) throws InterruptedException {
Scanner scan = new Scanner(System.in);
String line = scan.nextLine();
String words[] = line.split("\s");
Boolean done = false;
Object lock = new Object();
AtomicInteger index = new AtomicInteger(0);
int threads = 3;
for (int i = 0; i < threads; i++) {
new Thread(new Reader(i, words, lock, index, threads, done))
.start();
}
}
} | p*****3 发帖数: 488 | 2 看不懂程序,能说说这段程序的目的吗。感觉有点乱七八糟的。抛个砖头,等zhaoce和
二爷
只读为啥要多线程,构造函数咋啥都传进来了,AtomicInteger 不需要volatile修饰吧
,thread创建了咋没东西track,lock.wait后没有double check precondition,为啥要
swallow exception, 为啥要sleep,是不是可以用executionService
可以等都执行完了退出,比如像这样设置个done, 中断可以发interrupt, 线程要加判
断和处理interrupt的逻辑 | p*****2 发帖数: 21240 | 3
听说现在很少会用java的多线程了,都是用actor,gochannel这些东西,最不济也还有
STM呢。
【在 p*****3 的大作中提到】 : 看不懂程序,能说说这段程序的目的吗。感觉有点乱七八糟的。抛个砖头,等zhaoce和 : 二爷 : 只读为啥要多线程,构造函数咋啥都传进来了,AtomicInteger 不需要volatile修饰吧 : ,thread创建了咋没东西track,lock.wait后没有double check precondition,为啥要 : swallow exception, 为啥要sleep,是不是可以用executionService : 可以等都执行完了退出,比如像这样设置个done, 中断可以发interrupt, 线程要加判 : 断和处理interrupt的逻辑
| s******e 发帖数: 493 | 4 go read java concurrency in practice. There are many ways to handle end
signals among the threads. For example, completeService, barrier, latch, etc.
One thing for sure is that you do not want to use raw thread directly for
today unless you have a very good reason.
【在 n******1 的大作中提到】 : 自己练习写了一个多线程读一个字符串,但是没法退出,想请教两个问题 : 1.这种写法是我自己想出来,有没有更优雅一点的方法呢 : 2.线程间应该怎么通知结束信号然后退出的? : 感觉多线程难用的原因因为需要全部理解才能用好,一个地方没理解好,就用不好 : import java.util.Scanner; : import java.util.concurrent.atomic.AtomicInteger; : class Reader implements Runnable { : private int id; : private String[] queue; : private Object lock;
| l*******g 发帖数: 82 | 5 public void run() {
while (!done) {
synchronized (lock) { <---你这里加锁,最好放在while外
while (index.get() % threads != id) <---你这里判断条件
try {
lock.wait(); <---你这里是做什么?你如果想要wait(),
你就要有一个地方notify()。一旦你进入这里,你下面的notifyAll是永远都到达不了
的,因为你这个事wait forever!
} catch (Exception e) {
}
System.out.println("The id" + id + ": " + queue[index.get()]
);
if (index.incrementAndGet() == queue.length) {
done = true;
}
lock.notifyAll();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
我给你简单的说一下java线程中wait和sleep的用法。
sleep,顾名思义,就是睡眠,就是让当前线程睡眠一个给定的时间,然后自己继续执
行后面的代码。
wait/notify:一般情况是用来再一个内部条件的变化,会影响外部调用线程堵塞状态
的场景,简单来说,就是race condition,比如,你设计一个pool,一个method是take
,另一个是return,那么这个时候你就要用notify和wait。原因很简单,当take的时候
,如果出现pool没有东西可以给返回,那么就需要wait,你也可以理解成,告诉调用
take方法的线程等一下,而在等的时候,如果,一旦有另一个线程调用return方法还回
来一个item,那么就要呼叫notify或者notifyAll(区别自己花点时间研究),因为你
告诉那个正在等待的线程,”我们有新货了,来拿吧。“
多看点线程的文章,多练习一下比如写一个producer/consumer模式之类的。 |
|