我创建了一个简单的工人:
public class Worker {
public synchronized void writeData() {
try {
System.out.println("write Data , thread id = " + Thread.currentThread().getId());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void readData() {
try {
System.out.println("readData , thread id = " + Thread.currentThread().getId());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
AFAIK,如果多个线程访问同一个Worker
实例,同步的
只会阻止访问相同方法的线程。AKA如果线程A调用写数据,B使用读数据,它们不会相互影响(如果我错了,请纠正我)。
但是,当我试图用下面的代码演示它时:
private static void testWithThreads() {
final Worker worker = new Worker();
new Thread(() -> {
System.out.println("start read thread");
for (int i = 0; i < 20; i++) {
worker.readData();
}
}).start();
new Thread(() -> {
System.out.println("start write thread");
for (int i = 0; i < 20; i++) {
worker.writeData();
}
}).start();
}
我得到了这样的输出(请注意,我们在这里有 Thread.sleep
2 秒):
start read thread
readData , thread id = 10
start write thread
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
write Data , thread id = 11
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
readData , thread id = 10
谁能向我解释一下?他们似乎以某种方式互相阻止。
方法级别的< code>synchronized同步对方法所属对象的所有同步方法的访问,在该对象的任何同步方法中,只有一个线程可以执行。即使其他线程尝试访问第一个线程之外的其他< code>synchronized方法,它们也会等待。
其他线程将阻塞,直到第一个线程从同步块中出来。
在调用<code>for</code>循环中的同步方法之间的代码中,有一个很小的时间段,其他线程可以在第一次进入readData()之前进入writeData()-<code>的典型<code>循环不是原子操作-但这个时间段很小,这种情况很少发生-所以你的输出看起来像是在以某种方式互相阻挡-在某一点上,风向发生了变化,其他线程占据了主导地位。
更具体地说,注释指出每个for循环中“不同步”时隙的开始位置:
private static void testWithThreads() {
final Worker worker = new Worker();
new Thread(() -> {
System.out.println("start read thread");
for (int i = 0; i < 20; i++) {
worker.readData();
// any thread can now invoke writeData() if current thread is before next invocation of worker.readData();
}
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
System.out.println("start write thread");
for (int i = 0; i < 20; i++) {
worker.writeData();
// any thread can now invoke readData() if current thread is before next invocation of worker.writeData();
}
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
如果您想要更好的交错,您可以执行以下操作之一:
它的工作原理是,如果A为Worker实例使用writeData,那么B在获得机会之前,不能从同一Worker中使用readData或writeData。
如果你希望你的输出是:
读
写
读
写
等等...
那么我建议使用wait()函数;和notifyAll();这样,您可以使线程A在线程B完成后转一圈,反之亦然。
您可以在这里阅读有关wait()和notifyAll()的更多信息。
仅同步阻止访问相同方法的线程
不对。它阻塞试图在同一对象上同步的线程。
我如何启动两个线程,其中thread1首先执行,thread2在thread1结束时启动,而主方法线程可以在不锁定其他两个线程的情况下继续工作? 我尝试了join(),但是它需要从线程调用,线程必须等待另一个线程,没有办法执行类似thread2.join(thread1)的操作;因此,如果我在main()中调用join,我将有效地停止主线程的执行,而不仅仅是Thread2的执行。 #编辑:为什么我
我有一个很大的表,大约1米的记录,我想对所有的记录做一些处理,所以1个线程的方式,就是说。。。1000条记录,处理它们,再获得1000条记录等等。。。但如果我想使用多任务处理呢?也就是说,两个线程分别获取1000条记录,并并行处理,如何确保每个线程将获取不同的1000条记录?注意:我正在使用hibernate 好像是这样的
我有2个工作线程和1个处理线程。 当处理线程正在尝试处理某些事情,而辅助线程正在执行它们的工作时,处理线程应该等待,并且在辅助线程中执行的所有作业完成时唤醒。 我怎样才能唤醒这根线?我将尝试演示我在这段伪代码中的意思 处理线程类似于 这样的事情可能发生吗?让线程等待到多个调用notifyAll()的源,而不是只等待一次。我希望我把这个问题弄清楚了。 多谢帮忙!
我试着运行一个程序,使用线程显示带有数字的乘法、除法、加法和减法表。 但是我希望数字被乘以或相加等。由用户选择。 也就是说,程序应该在用户为每个操作选择一个数字后运行,然后显示结果。
我有一个python脚本,所以我在python中使用线程模块并发执行。 def run(self):db=MySQLdb。connect('localhost','mytable','user','mytable')游标=db。cursor()query=“dig short”str(反向ip)”按键try:output=子进程。检查\u输出(查询,shell=True)输出\u编辑=输出。条带(
下面是