java多线程问题
下面是代码的一部分。我很困惑为什么“通知1”不能真正唤醒另一个正在等待的函数java多线程问题,java,multithreading,Java,Multithreading,下面是代码的一部分。我很困惑为什么“通知1”不能真正唤醒另一个正在等待的函数 MultiThreadContent m; void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{ . . . //run from he
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
这与:
当一个线程为一个对象执行同步方法时,调用同一对象块的同步方法的所有其他线程(暂停执行),直到第一个线程对该对象执行完毕
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
为什么结果不是:
等待
通知1,
等我说完,
通知2,
.
.
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
相反,它是:
等待
通知1,
通知2,
通知2,
.
.
.
通知2,
通知2,
通知3,
等我说完,
跳过等待,
跳过等待,
跳过等待,
.
.
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
代码
{
.
.
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
multi-threadm;
void divideToParts(文件testFile、文件inputstream、文件inputstream、对象hashMachine)引发IOException、InterruptedException{
.
.
.
//从这里跑
m=新的多线程内容(fileInputStream,(int)temp23,(int)(testFile.length()%temp23),numberOfParts,hashMachine);
新线程(新读取()).start();
m、 更新();
}
类读取实现可运行{
@凌驾
公开募捐{
试一试{
m、 read();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
类多线程内容{
.
.
.
布尔值preNotReady=true;
布尔更新完成;
//阅读{
public synchronized void read()引发InterruptedException{
//首字母{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println(“通知1”);//d
如果(FinisheDreard!=真)
{
readNextBlock();
read_wait();
}
其他的
返回;
//}
while(finishedeard!=真){
preBlock=nextBlock;
read_notify();
System.out.println(“通知2”);//d
readNextBlock();
read_wait();
}
//结束{
preBlock=nextBlock;
read_notify();
System.out.println(“notify 3”);//d
//}
}
无效读取通知(){
preNotReady=假;
notifyAll();
}
void read_wait()引发InterruptedException{
if(updateNotFinished==true)
{
等待();
System.out.println(“等待更新”);//d
}
preNotReady=真;
}
//}
//更新{
public synchronized void update()引发InterruptedException{
对于(int i=0;i
我不知道这是否是您遇到的问题,但它肯定会成为一个问题。对.wait()的所有调用都必须包含在while循环中。对wait()的调用可以随机唤醒
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
正如:“在单参数版本中,中断和虚假唤醒是可能的,并且这种方法应该始终在循环中使用:”我不知道这是否是您遇到的问题,但它肯定会成为一个问题。对.wait()的所有调用都必须包含在while循环中。对wait()的调用可以随机唤醒
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
根据:“在单参数版本中,中断和虚假唤醒是可能的,并且此方法应始终在循环中使用:”原因是您没有离开同步块。read_wait方法从不进入if块,因为updateNotFinished默认初始化为false。由于read_wait从不进入if块,因此您将继续循环
finishedeard=正确
。在退出该方法和同步块之前,您永远不会放弃对监视器的控制
完成后,锁可用,另一个线程被正确唤醒
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
要测试我说的内容,请尝试在初始化时设置
updateNotFinished=true
。原因是您没有离开同步块。read_wait方法从不进入if块,因为updateNotFinished默认初始化为false。由于read_wait从不进入if块,因此您将继续循环finishedeard=正确
。在退出该方法和同步块之前,您永远不会放弃对监视器的控制
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
完成后,锁可用,另一个线程被正确唤醒
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
要测试我所说的内容,请尝试在初始化时设置
updateNotFinished=true
。我发现较新的并发库比wait()/notify()更易于使用。添加这些库是有原因的,它们非常值得学习。下面是一个如何简化代码的示例
MultiThreadContent m;
void divideToParts(File testFile,FileInputStream fileInputStream, Object hashMachine) throws IOException, InterruptedException{
.
.
.
//run from here
m = new MultiThreadContent(fileInputStream,(int)temp23,(int) (testFile.length()%temp23), numberOfParts, hashMachine);
new Thread(new Read()).start();
m.update();
}
class Read implements Runnable{
@Override
public void run() {
try {
m.read();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MultiThreadContent{
.
.
.
boolean preNotReady=true;
boolean updateNotFinished;
//read{
public synchronized void read() throws InterruptedException{
//initial{
readNextBlock();
preBlock=nextBlock;
read_notify();
System.out.println("notify 1");//d
if(finishedRead!=true)
{
readNextBlock();
read_wait();
}
else
return;
//}
while(finishedRead!=true){
preBlock=nextBlock;
read_notify();
System.out.println("notify 2");//d
readNextBlock();
read_wait();
}
//closing{
preBlock=nextBlock;
read_notify();
System.out.println("notify 3");//d
//}
}
void read_notify(){
preNotReady=false;
notifyAll();
}
void read_wait() throws InterruptedException{
if(updateNotFinished==true)
{
wait();
System.out.println("wait for update");//d
}
preNotReady=true;
}
//}
//update{
public synchronized void update() throws InterruptedException{
for (int i = 0; i < totalParts; i++) {
update_wait();
divideToParts_update(hashMachine, preBlock);
update_notify();
}
}
void update_notify(){
updateNotFinished=false;
notifyAll();
}
void update_wait() throws InterruptedException{
if(preNotReady){
System.out.println("wait");//d
wait();
System.out.println("wait finish");//d
}
updateNotFinished=true;
System.out.println("skip wait");//d
}
//}
}
}
String filename = ...
ExecutorService es = Executors.newFixedThreadPool(5);
FileInputStream fis = new FileInputStream(filename);
while (true) {
final byte[] buffer = new byte[8 * 1024];
final int len = fis.read(buffer);
if (len < 0) break;
es.submit(new Runnable() {
public void run() {
process(buffer, len);
}
});
}
fis.close();
es.shutdown();
es.awaitTermination(60, TimeUnit.MINUTES);
字符串文件名=。。。
Executors服务es=Executors.newFixedThreadPool(5);
FileInputStream fis=新的FileInputStream(文件名);
while(true){
最终字节[]buf