我对Java和多线程没有经验,所以也许你们可以帮忙。多线程时,在TextArea框中打印一系列数字和字母时遇到问题。这是我的代码:
public class MultiThread extends Application {
static TextArea outputArea = new TextArea();
@Override
public void start(Stage primaryStage) throws Exception {
outputArea.setWrapText(true);
Runnable printA = new PrintChar('a', 100);
Runnable printB = new PrintChar('b', 100);
Runnable print100 = new PrintNum(100);
// Create threads
Thread thread1 = new Thread(printA);
Thread thread2 = new Thread(printB);
Thread thread3 = new Thread(print100);
thread1.start();
thread2.start();
thread3.start();
Scene scene = new Scene(outputArea, 250, 130);
primaryStage.setTitle("Concurrent Output");
primaryStage.setScene(scene);
primaryStage.show();}
public static void main(String[] args) {
launch(args);
}
}
class PrintChar extends MultiThread implements Runnable {
private char charToPrint; // The character to print
private int times; // The times to repeat
public PrintChar(char c, int t) {
charToPrint = c;
times = t;
}
@Override
public void run() {
for (int i = 0; i < times; i++) {
outputArea.appendText(charToPrint + "");
}
}
}
class PrintNum extends MultiThread implements Runnable {
private int lastNum;
private char charToPrint;
public PrintNum(int n) {
lastNum = n;
}
@Override
public void run() {
for (int i = 1; i <= lastNum; i++) {
outputArea.appendText(i + "");
}
}
}
当我运行代码时,线程通常不会打印出它们应有的全部内容。例如,“ print100”并不总是像预期的那样打印到100号。我也会得到随机结果,而每次都不会得到相同的输出也不会出错。
Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IndexOutOfBoundsException
at javafx.scene.control.TextInputControl.getText(TextInputControl.java:451)
at javafx.scene.control.TextInputControl.updateContent(TextInputControl.java:564)
at javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:548)
at javafx.scene.control.TextInputControl.insertText(TextInputControl.java:473)
at javafx.scene.control.TextInputControl.appendText(TextInputControl.java:463)
at threader.PrintChar.run(Threader.java:53)
at java.lang.Thread.run(Thread.java:748)
java.lang.IndexOutOfBoundsException
at javafx.scene.control.TextInputControl.getText(TextInputControl.java:451)
at javafx.scene.control.TextInputControl.updateContent(TextInputControl.java:555)
at javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:548)
at javafx.scene.control.TextInputControl.insertText(TextInputControl.java:473)
at javafx.scene.control.TextInputControl.appendText(TextInputControl.java:463)
at threader.PrintNum.run(Threader.java:71)
at java.lang.Thread.run(Thread.java:748)
我几乎可以肯定的是,同步代码中的多个线程是一个问题,但是我似乎无法弄清楚该特定代码如何实现。
答案 0 :(得分:1)
#include <bcm2835.h>
#include <stdio.h>
// PWM output on RPi Plug P1 pin 12 (which is GPIO pin 18)
// in alt fun 5.
// Note that this is the _only_ PWM pin available on the RPi IO headers
#define PIN RPI_GPIO_P1_12
// and it is controlled by PWM channel 0
#define PWM_CHANNEL 0
// This controls the max range of the PWM signal
#define RANGE 1024
int main(int argc, char **argv)
{
if (!bcm2835_init())
return 1;
// Set the output pin to Alt Fun 5, to allow PWM channel 0 to be output there
bcm2835_gpio_fsel(PIN, BCM2835_GPIO_FSEL_ALT5);
// Clock divider is set to 16.
// With a divider of 16 and a RANGE of 1024, in MARKSPACE mode,
// the pulse repetition frequency will be
// 1.2MHz/1024 = 1171.875Hz, suitable for driving a DC motor with PWM
bcm2835_pwm_set_clock(BCM2835_PWM_CLOCK_DIVIDER_16);
bcm2835_pwm_set_mode(PWM_CHANNEL, 1, 1); //CTL reg
bcm2835_pwm_set_range(PWM_CHANNEL, RANGE); //RNG1/2 reg
// Vary the PWM m/s ratio between 1/RANGE and (RANGE-1)/RANGE
int direction = 1;
int data = 1;
while (1)
{
if (data == 1)
direction = 1;
else if (data == RANGE-1)
direction = -1;
data += direction;
bcm2835_pwm_set_data(PWM_CHANNEL, data);
bcm2835_delay(1);
}
bcm2835_close();
return 0;
}
实现显然不是线程安全的,因此在调用 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xxx">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:allowBackup="false"
android:theme="@style/AppTheme"
android:hardwareAccelerated="true"
android:largeHeap="true"
android:usesCleartextTraffic="true"
>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".NotifierActivity"
android:label="SOS"
android:icon="@mipmap/ic_launcher_sos"
android:roundIcon="@mipmap/ic_launcher_sos_round"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
对象上的方法时,应确保当前线程没有中断。例如,您可以通过同步TextArea
对象本身来做到这一点:
TextArea
答案 1 :(得分:1)
在MultiThread
类中创建静态函数,如下所示:
public static synchronized setText(String str) {
outputArea.appendText(str);
}
,并将行outputArea.appendText(...);
替换为MultiThread.setText(...)
。
问题:您当前正在通过三个线程在outputArea上设置文本,并且它们一次都试图将文本添加到outputArea上。因此,outputArea中用于附加文本的索引与另一个线程重叠。
解决方案:确保只有一个线程尝试在outputArea上追加文本。