1 进程和线程
进程Process: 每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。可以把进程简单理解为操作系统中运行的一个程序。
线程Thread:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。
线程是进程的一个执行分支
创建线程就是创建Thread类(子类)的对象(实例)
java.lang.Thread
- public class Thread extends Object implements Runnable
一个线程的周期
继承Thread类
class ThreadTest extends Thread{
public void run(){
System.out.println("这个线程开始运行");
}
}
public class Test {
public static void main(String[] args) {
ThreadTest tt = new ThreadTest ();
tt.start(); //启动一个线程
}
}
实现Runnable接口
class ThreadTest implements Runnable{
public void run(){
System.out.println("这个线程开始运行");
}
}
public class Test {
public static void main(String[] args) {
ThreadTest tt = new ThreadTest ();
Thread t = new Thread(tt);
t.start(); //通过一个线程对象启动它
}
}
这两种方式的区别:
1、继承Thread类:编写简单,可直接操作线程。适用于单继承
2、实现Runnable接口:避免单继承局限性,便于共享资源。
线程的优先级
ThreadTest t1 = new ThreadTest();
t1.setPriority(1); //设置成最低级
ThreadTest t2 = new ThreadTest();
t2.setPriority(10); //设置成*
t1.start();
t2.start();
Java线程有优先级,优先级高的线程会获得较多的CPU运行机会。Thread类的setPriority()和getPriority()方法分别用来设置和获取线程的优先级。 Java线程的优先级用整数表示,取值范围是1~10; 10*。每个线程都有默认的优先级。主线程的默认优先级为Thread.NORM_PRIORITY(5)
线程睡眠
class ThreadTest extends Thread{
public void run(){
for(int i=0;i<10;i++){
System.out.println(i);
try {
Thread.sleep(1000); //每隔一秒后输出
} catch (InterruptedException e) { //线程睡眠期间如果被打断,将抛出异常。
e.printStackTrace();
}
}
}
}
Thread.sleep() 强迫线程睡眠(单位:毫秒)
合并线程
join()的功能是:等待某线程结束,再恢复当前线程的运行
或者说:join()把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程
class ThreadTest extends Thread{
public void run(){
for(int i=0;i<10;i++){
System.out.println(this.getName() + ":" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//相当于将tt线程和main线程合并成一个线程。
//那么main线程会等待tt线程结束后再运行。
public static void main(String[] args) {
ThreadTest tt = new ThreadTest ();
tt.start();
try {
tt.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0;i<10;i++){
System.out.println("main:" + i);
}
}
让出CPU资源
yield() 让出CPU资源,当前线程进入就绪状态
class ThreadTest extends Thread{
public void run(){
for(int i=0;i<100;i++){
System.out.println(this.getName() + ":" + i);
if(i%10==0){
Thread.yield();
}
}
}
}
public static void main(String[] args) {
ThreadTest tt1 = new ThreadTest ();
ThreadTest tt2 = new ThreadTest ();
tt1.start();
tt2.start();
}
线程等待与唤醒
wait():当前线程进入等待状态,即进入等待池。(释放同步锁,由notify()唤醒);
notify()/notifyAll():唤醒等待池中的某个或全部等待线程。