说到线程,就不得不提到进程。那就区分一下他俩的区别
进程和线程异同
进程:是指计算机运行的一个软件(程序),每个进程都有独自的代码和数据空间,进程间的切换会有很大的开销。
线程:一个程序内部的多个控制流,一个进程可以包括多个线程,线程之间切换开销很小。
多进程:操作系统可以同时运行多个进程(程序)
多线程:在同一个程序中有个线程执行,叫多线程。
线程实现的两种方式
1.继承Thread类,重写run()方法
public class 类名 extends Thread{
@overrid
public void run(){
//该线程实现的功能
}
}
线程的开始
先创建自己线性的对象
然后线程对象.start()
2.实现Runnable接口
public class 类名 implements Runnable{
public void run(){
//该线程实现的功能
}
}
线程的开始:
先创建自己的Runnable类的对象
然后创建Thread对象 Thread 对象 = newThread(Runnable对象);
然后Thread对象调用start()
比较
继承(单一继承)、接口
这两种方式本质上都是调用了Thread的run方法
线程状态及生命周期
包含等待的线程状态
线程对象从start开始到结束,期间存在不同的状态
创建 new
就绪状态 线程对象调用start方法后
运行状态 被线程调度器执行
堵塞状态 当运行中的线程产生堵塞事件时,进入堵塞状态
停止状态 线程运行完成,或者运行过程中产生异常。
线程中的主要方法
sleep(millis) Thread类的静态方法,接收一个以毫秒为单位的参数,表示让线程休眠多少毫秒
比如该线程休眠1000毫秒: Thread.sleep(1000); 需要注意,处理检查性的异常。
join() 在一个线程A中使用另一个线性对象B调用join()方法,表示在该线程A中等待另一个线程B的执行结束后再继续执行A线程。
yield() 让出cpu,进入就绪状态
isAlive() 判断线程是否存活
wait()是该对象上的当前线程进入等待状态
notify()唤醒该对象上的其他线程
notifyAll()唤醒该对象上的其他线程
线程的同步
如果涉及到多个线程操作同一个资源,会产生问题。
同步是指多个线程同时操作同一个资源时,需要一个结束之后,另一个再来操作,保证同一个时间点,只有一个线程操作这个资源。
至少有一个线程修改这个资源时,需要线程同步。如果多个线程仅仅读取资源,不需要同步。
线程同步使用关键字synchronized来进行同步,主要有两种形式:
synchronized修饰一段代码块
使用synchronized修饰对同一资源操作的代码块,需要传入一个对象,可以传入this。
synchronized(对象){
//代码块
}
synchronized修饰一个方法
表示同一个时刻只能有一个线程来调用该方法,其他线程不能调用相同对象的该方法,只能等占用的线程完成后才能继续调用。
例子
用线程实现功能:线程1输出1,3,5...97,99 ,线程2输出2,4,6....98,100 ,要求两个线程开始后,按顺序输出1,2,3,4,5....99,100
public class ThreadDemo extends Thread{
private static int count = 0; //初始条件
private int start;
private int end;
TestThread t = new TestThread();
@Override
public void run() {
synchronized (t) {//同步代码块
// System.out.println(Thread.currentThread().getName());
count++;
for(int i = start+count;i <= end+count;i += 2) {
System.out.print(i+",");
t.notify(); //唤醒另一个线程
try {
t.wait(); //本线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
t.notify();//最后唤醒本线程,程序结束
}
}
public ThreadDemo(int start,int end) {
this.start = start;
this.end = end;
}
}
测试代码
public class TestThread {
public static void main(String[] args) throws InterruptedException {
// Object object = new Object();
ThreadDemo test1 = new ThreadDemo(0,98);
Thread t1 = new Thread(test1);
Thread t2 = new Thread(test1);
// t1.setPriority(10);
// t2.setPriority(8);
t1.setName("线程一");
t2.setName("线程二");
t1.start();
// t1.join();
t2.start();
}
}