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());
}
});
}
}
}
如果您按下第一个按钮(Start Threads without Join),这将是结果:
如果您按下第二个按钮(Start Threads With Join),这将是结果: