进程
是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间
线程
是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行. 一个进程最少有一个线程。
线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径又可以划分成若干个线程。
线程调度
作用:更合理地利用cpu。
分类:
1、分时调度-给线程平均分配时间
2、抢占式调度-按照优先级选择线程
前者是雨露均沾,就像老师大班授课,每个学生的上课时间是一样的;后者是区别对待,老师会按照学习能力高低来决定给学生辅导时间长短。
同步与异步
同步:排队执行 , 效率低但是安全.
异步:同时执行 , 效率高但是数据不安全
并发与并行
并发:指两个或多个事件在同一个时间段内发生。
并行:指两个或多个事件在同一时刻发生(同时发生)。
创建新线程的方法
1、继承Thread类
关键字:重写run方法、调用start方法
public class MyThreadTest{
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
for(int i = 0;i < 10;i++) {
System.out.println("main线程");
}
}
}
class MyThread extends Thread{
@Override
public void run() {
for(int i = 0;i < 10;i++) {
System.out.println("新线程");
}
}
}
2、实现Runable
实现Runnable与继承Thread相比有如下优势:
1,通过创建任务,然后给线程分配任务的方式实现多线程,更适合多个线程同时执行任务的情况;
2,可以避免单继承所带来的局限性(Java允许实现多个接口,但不允许继承多个父类);
3,任务与线程是分离的,提高了程序的健壮性;
4,后期学习的线程池技术,接受Runnable类型的任务,不接受Thread类型的线程;
设置和获取线程名称
public class MyThreadTest{
public static void main(String[] args) {
MyThread m = new MyThread("newName");
m.start();
}
}
class MyThread extends Thread{
//设置线程名字
public MyThread(String name) {
this.setName(name);
}
@Override
public void run() {
//获取线程名字
System.out.println("新线程:"+Thread.currentThread().getName());
}
}
线程休眠
Thread.sleep();
线程阻塞
当前线程没有执行完成导致下一个线程不能执行的这种情况就叫线程阻塞,就像堵车一样。
线程的中断
中断就是结束的意思。使用interrupt方法可以使线程结束,以前用的是stop方法。前者是自杀,后者是他杀(强制结束),因为一个线程在运行过程中可能会占用一些资源,如果他杀,会导致资源无法释放,所以stop已经被淘汰,下面是一个自杀的例子。
public class MyThreadTest{
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
for(int i = 0;i < 10;i++) {
System.out.println("main线程"+i);
}
m.interrupt();
}
}
class MyThread extends Thread{
@Override
public void run() {
for(int i = 0;i < 10;i++) {
System.out.println("新线程");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("我被打上中断标记了,我要自杀了"+i);
return;
}
}
}
}
守护线程
线程有两种,分为用户线程和守护线程。守护线程就是给用户线程加一个方法(setDaemon),这个方法就是随用户线程一起结束。
同步代码块
public class TicketTest {
public static void main(String[] args) {
Ticket tic = new Ticket();
Thread t1 = new Thread(tic);
Thread t2 = new Thread(tic);
Thread t3 = new Thread(tic);
t1.start();
t2.start();
t3.start();
}
}
class Ticket implements Runnable{
private int count = 10;
Object o = new Object();
@Override
public void run() {
while(true) {
synchronized(o) {
if (count>0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"窗口正在出票");
System.out.println("出票成功,余票:"+count);
} else {
break;
}
}
count--;
}
}
}