join()方法用于暂停当前正在运行的线程,直到指定的线程死亡(执行完成)。
为什么要使用join()方法?
在正常情况下,我们通常有多个线程,线程调度程序安排线程,但不能保证线程执行的顺序。
让我们看一个例子,创建一个新项目并复制以下代码:
这是activity_main.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_without_join"
app:layout_constraintTop_toTopOf="parent"
android:text="Start Threads Without Join"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_with_join"
app:layout_constraintTop_toBottomOf="@id/btn_without_join"
android:text="Start Threads With Join"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tv"
app:layout_constraintTop_toBottomOf="@id/btn_with_join"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
这是MainActivity.java的代码:
public class MainActivity extends AppCompatActivity {
TextView tv;
volatile String threadName = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = findViewById(R.id.tv);
Button btn_without_join = findViewById(R.id.btn_without_join);
btn_without_join.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
withoutJoin();
}
});
Button btn_with_join = findViewById(R.id.btn_with_join);
btn_with_join.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
withJoin();
}
});
}
private void withoutJoin()
{
tv.setText("");
Thread th1 = new Thread(new MyClass2(), "th1");
Thread th2 = new Thread(new MyClass2(), "th2");
Thread th3 = new Thread(new MyClass2(), "th3");
th1.start();
th2.start();
th3.start();
}
private void withJoin()
{
tv.setText("");
Thread th1 = new Thread(new MyClass2(), "th1");
Thread th2 = new Thread(new MyClass2(), "th2");
Thread th3 = new Thread(new MyClass2(), "th3");
th1.start();
try {
th1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
th2.start();
try {
th2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
th3.start();
}
class MyClass2 implements Runnable{
@Override
public void run() {
Thread t = Thread.currentThread();
runOnUiThread(new Runnable() {
public void run() {
tv.setText(tv.getText().toString()+"\n"+"Thread started: "+t.getName());
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
tv.setText(tv.getText().toString()+"\n"+"Thread ended: "+t.getName());
}
});
}
}
}
如果您按下第一个按钮(启动未加入的线程),将会得到以下结果:
如果您按下第二个按钮(启动已加入的线程),将会得到以下结果:
while(true)
来调用join
方法。 - Arefe