进程:系统可以进行独立调配并且是一个不可分割 独立单元
开启一个任务管理器,很多进程(应用软件/某些客户端)
什么是多进程?
多进程的意义:是为了提高CPU的使用率
现在计算机都是多进程,假设:在听音乐的同时,也在打游戏..,他们是同时进行的吗?
他们不是同时进行的,感觉同时,一点点CPU的时间片在同一个时刻在两个进程之间进行高效的切换!
什么线程?
线程:进程的一个独立的单元
一个进程里面有多个任务,把每一个任务看成一个线程
多线程:
线程之间在抢占CPU的执行权(抢占资源)
多线程的执行具有随机性
举例"
打篮球:1v1 两个人抢占篮球的几率同样大
1v5 5个人抢占篮球的几率大,并不能说一定抢到 (随机性的)
如何实现多线程程序呢?
要实现多线程程序,需要开启进程,
开启进程,是需要创建系统资源,但是Java语言不能创建系统资源
只有C/C++可以创建系统资源, 利用c语言创建好的系统资源实现
Java提供了一个类:Thread类
实现多线程程序的步骤:
1)将类声明为 Thread 的子类
2)该子类应重写 Thread 类的 run 方法
3)在主线程进行该自定义的线程类的对象的创建
并行和并发(高并发:MyBatis --->IBatis:半自动化)
强者逻辑上的同时,指的是同一个时间段内
后者物理上的同时,指的是同一个时间点
MyThread类就是一个执行线程类
并且重写Thread类中的run 方法
run()方法里面应该是一些耗时的操作,IO操作/循环语句..
public class MyThread extends Thread {
@Override
public void run() {
// System.out.println("helloworld");
for(int x = 0 ;x <300; x ++) { //两个线程都需要执行这个代码
System.out.println(x);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
//创建MyThread类对象
MyThread t1 = new MyThread() ;
t1.start();
//IllegalThreadStateException:非法状态异常,同一个线程只能被执行一次
// t1.start();
MyThread t2 = new MyThread() ;
t2.start();
}
}
JVM:Java虚拟机 识别main(主线程)
面试题:JVM是多线程程序吗?至少有几条线程..
jvm是多线程的,
至少有2条线程...
有主线程,main..执行这些代码,能够被Jvm识别
在执行一些程序的时候,一些对象Jvm释放掉,原因,
它开启了垃圾回收线程,里面GC:垃圾回收器(回收一些没有更多引用的对象或者变量...)
public class Demo {
public static void main(String[] args) {
System.out.println("hello");
new Object() ;
new Object() ;
new Object() ;
new Object() ;
new Object() ;
//......n个
System.out.println("world");
}
}
//第一种:继承关系Extends
public class MyThread extends Thread {
public MyThread() {
}
public MyThread(String name) {
super(name) ;
}
@Override
public void run() {
for(int x = 0 ;x < 100 ; x++) {//t1,t2
System.out.println(getName()+":"+x); //thread-线程编号(从0开始)
}
}
}
Thread 类提供了一些方法
public final void setName(String name):给线程起名称public final String getName() :获取线程名称
public class ThreadDemo {
public static void main(String[] args) {
//创建两个线程对象
/* MyThread my1 = new MyThread() ;
MyThread my2 = new MyThread() ;
//启动线程
my1.start();
my2.start();*/
//给线程起名字:无参构造的形式+setName()
/*MyThread my1 = new MyThread() ;
MyThread my2 = new MyThread() ;
//给线程起名字
// my1.setName("高圆圆");
// my2.setName("张杨");
//分别启动
my1.start();
my2.start();*/
System.out.println("------------");
//public Thread(String name):有参构造的形式
MyThread t1 = new MyThread("张三") ;
MyThread t2 = new MyThread("李四") ;
t1.start();
t2.start();
//Thread类中提供另一个功能:
//public static Thread currentThread():返回当前正在执行的线程对象的引用
System.out.println(Thread.currentThread().getName());//main
}
}
public final void setDaemon(boolean on) :true时,表示为守护线程
将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。(守护线程不会立即结束掉,它会执行一段时间在结束掉)该方法必须在启动线程前调用。
public class ThreadDaemonDemo {
public static void main(String[] args) {
//创建两个子线程
ThreadDaemon td1 = new ThreadDaemon() ;
ThreadDaemon td2 = new ThreadDaemon() ;
td1.setName("张飞");
td2.setName("关羽");
//在启动之前,设置为守护线程
td1.setDaemon(true);
td2.setDaemon(true);
td1.start();
td2.start();
Thread.currentThread().setName("刘备");
for(int x =0 ; x < 5 ; x ++) {
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}
public class MyThread extends Thread {
@Override
public void run() {
for(int x = 0 ; x <100 ; x ++) {
System.out.println(getName()+":"+x);
}
}
}
跟线程优先级相关的方法:
public final int getPriority()返回线程的优先级。public final void setPriority(int newPriority)更改线程的优先级
线程存在一个默认优先级
public static final int MAX_PRIORITY 10 最大优先级
public static final int MIN_PRIORITY 1 最小优先级
public static final int NORM_PRIORITY 5 默认优先级
public class ThreadDaemon extends Thread {
@Override
public void run() {
for(int x = 0 ; x<100; x ++) {
System.out.println(getName()+":"+x);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
//创建三个子线程
MyThread t1 = new MyThread() ;
MyThread t2 = new MyThread() ;
MyThread t3 = new MyThread() ;
// System.out.println(t1.getPriority()); //5 默认优先级
// System.out.println(t2.getPriority());
// System.out.println(t3.getPriority());
t1.setName("林青霞");
t2.setName("林志颖");
t3.setName("林彪");
//设置线程优先级
t1.setPriority(10);
t2.setPriority(1);
t3.setPriority(5);
t1.start();
t2.start();
t3.start();
}
}
public final void join():等待该线程终止 interruputedException 中断异常
分别创建三个子线程,让第一个子线程执行之后,调用join()等待该线程中,在执行t2,t3线程
public class ThreadJoin extends Thread {
@Override
public void run() {
for(int x = 0 ; x < 100 ; x ++) {
System.out.println(getName()+":"+x);
}
}
}
public class ThreadJoinDemo {
public static void main(String[] args) {
//创建三个子线程
ThreadJoin t1 = new ThreadJoin() ;
ThreadJoin t2 = new ThreadJoin() ;
ThreadJoin t3 = new ThreadJoin() ;
//分别给线程设置名称
t1.setName("李渊");
t2.setName("李世明");
t3.setName("李元霸");
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
t3.start();
}
}
public static void sleep(long millis):线程睡眠 指定是时间毫秒值
throws InterruptedException两个区别?
public final void stop() ;强迫线程停止执行。 不会执行了 (过时了),方法能使用的
public void interrupt()中断线程。 表示中断线程的一种状态
面试题
区别?
wait(): wait()调用的,立即释放锁 (同步锁/Lock锁)
sleep(): 线程睡眠,调用不会释放锁
import java.util.Date;
public class ThreadSleep extends Thread {
@Override
public void run() {
for(int x = 0 ; x <100 ; x ++) {
//t1,t2
//t1, 0,1 //t2来了 ,3,4,5,6,7,8 //t1 2 ,,,
System.out.println(getName()+":"+x+",日期是:"+new Date());
//困了,想睡一秒钟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadSleepDemo {
public static void main(String[] args) {
//创建两个子线程
ThreadSleep ts1 = new ThreadSleep() ;
ThreadSleep ts2 = new ThreadSleep() ;
ts1.setName("张三");
ts2.setName("李四");
ts1.start();
ts2.start();
}
}
public final void stop() ;强迫线程停止执行。 不会执行了 (过时了),方法能使用的
public class ThreadStop extends Thread {
@Override
public void run() {
System.out.println("程序开始了....");
//睡秒10秒钟
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// e.printStackTrace();
System.out.println("程序出现异常了...");
}
System.out.println("程序结束了....");
}
}
public class ThreadStopDemo {
public static void main(String[] args) {
//创建ThreadStop类对象
ThreadStop st = new ThreadStop() ;
st.start() ;
//如果3秒不醒来,我就干掉你
try {
st.sleep(3000);
// st.stop();
st.interrupt();// 中断
} catch (InterruptedException e) {
// e.printStackTrace();
System.out.println("程序出现了中断异常");
}
}
}
public static void yield()暂停当前正在执行的线程对象,并执行其他线程
public class ThreadYield extends Thread {
@Override
public void run() {//t1,t2子线程线程都要执行这个run()方法
for(int x = 0 ;x <100 ; x ++) {
System.out.println(getName()+":"+x);//
}
Thread.yield();
}
}
public class ThreadyieldDemo {
public static void main(String[] args) {
//创建两个子线程对象
ThreadYield ty1 = new ThreadYield() ;
ThreadYield ty2 = new ThreadYield() ;
ty1.setName("张三");
ty2.setName("李四");
//分别启动线程
ty1.start();
ty2.start();
}
}
实现多线程程序的第二种方式:
1)自定义一个类,实现Runnable接口2)实现接口中的run方法,对耗时的代码进行操作
3)然后在主线程中创建该了对象,将该类对象做为一个资源类,创建Threadd类的对象,将刚才的资源类作为参数进行传递
//自定义类实现接口,实现run方法
public class MyThread implements Runnable {
@Override
public void run() {
for(int x= 0; x <100 ; x ++) {
// System.out.println(getName()+":"+x);
System.out.println(Thread.currentThread().getName()+":"+x);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
//创建当前类对象
MyThread my =new MyThread() ;
//实现多线程
//public Thread(Runnable target,String name)
Thread t1 = new Thread(my, "高圆圆") ;
Thread t2 = new Thread(my, "赵又廷") ;
//启动线程
t1.start();
t2.start();
}
}