如何等待线程创建对象?

时间:2019-04-07 19:04:28

标签: java android multithreading sockets null

在我的Android应用中,我需要在两个应用之间发送数据。当GameClient初始化后,它将启动三个线程。 第一个将创建一个Socket和ReceivingThread。我需要在一个线程中执行此操作,因为Android不允许我在MainThread上进行网络连接:

new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            if (mSocket == null) {
                setSocket(new Socket(mAddress, mPort));
                Log.d(TAG, "Client-Socket set.");
            } else {
                Log.d(TAG, "Socket already set. Skip.");
            }
            mRecCardThread = new ReceivingCardThread();
            mRecCardThread.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();
mSendCardThread = new SendingCardThread();
mSendCardThread.start();

此后,我创建了第三个用于发送数据的线程。

当我连接到另一部电话并立即要发送一些数据时,会发生问题。

mConnection.connectToServer(d.getHost(), d.getPort());
mConnection.sendCard(new int[]{0, 0, 0});

我的发送线程试图发送数据,但是通常比setSocket方法更早被调用。

private synchronized void setSocket(Socket socket) {
    Log.d(TAG, "setSocket called");
    if (mSocket != null) {
        if (mSocket.isConnected()) {
            try {
                mSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    mSocket = socket;
    if (mClient != null)
        mClient.mSendCardThread.notifyAll();
    Log.d(TAG, "Notify all, that Socket is set");
}

private class SendingCardThread extends Thread {
    BlockingQueue<int[]> mCardQueue = new ArrayBlockingQueue<>(10);
    private ObjectOutputStream mOutput;

    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                int[] nums = mCardQueue.take();
                sendCard(nums);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private synchronized void sendCard(int[] nums) {
        try {
            if (mOutput == null) {
                while (mSocket == null) {
                    Log.d(TAG, "Waiting for Socket to be set.");
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.d(TAG, "Not waiting anymore.");
                }
                mOutput = new ObjectOutputStream(mSocket.getOutputStream());
            }
            mOutput.writeObject(nums);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Log.d(TAG, "Client send:" + Arrays.toString(nums));
    }
}

因此,我想让Socket仍为null时以及创建Socket时唤醒发送线程,以唤醒发送线程以确保Socket开头不为空。 / p>

但这会导致IllegalMonitorStateException:对象在notifyAll()之前没有被线程锁定。 因此,似乎它尝试进行通知,但发送线程没有等待。但是我不知道如何解决这个问题。我还认为我不理解如何在praxice中使用wait()和notify()。

我希望你们中的一个能帮助我解决这个愚蠢的问题; D

0 个答案:

没有答案