Java线程
1.进程和线程
进程:程序运行依赖一个或多个线程
线程:进程运行依赖多个线程,线程是操作系统能够调度的最小单位
2.并发和并行
并发:一个CPU同时执行多个程序
并行:多个CPU同时执行多个程序
3.线程的状态/线程的生命周期
1)新建状态(New):new对象是为新建状态
2)就绪状态(Runnable):调用start()方法后为就绪状态,该线程已准备就绪,等待CPU的调度执行,就绪状态是运行状态的唯一入口
3)运行状态(Running):就绪状态的线程得到CPU的调度执行
4)阻塞状态(blocked):运行状态的线程失去CPU的执行,挂起等待再次进入就绪状态
5)终止状态(Dead):线程执行完毕或者异常退出run()方法,线程的生命周期结束
阻塞状态有三种:
(1)运行阻塞:线程执行wait()方法
(2)同步阻塞:线程获取synchronized同步锁失败,进入同步阻塞状态
(3)其他阻塞:通过调用线程的sleep()、join()、或者I/O请求时,会进入阻塞状态,等待sleep()超时、join()线程终止或超时、或者I/O请求处理完毕时,线程重新进入就绪状态
多线程例子
继承Thread类
public class MyThread {
public static void main(String[] args) {
Thread1 t1 = new Thread1();
Thread1 t2 = new Thread1();
Thread1 t3 = new Thread1();
t1.setName("a");
t2.setName("b");
t3.setName("c");
t1.start();
t2.start();
t3.start();
}
}
//解决线程问题可选方法同步锁
class Thread1 extends Thread {
//num>50时,多个线程对50进行减1
//int num=50; 继承Thread类实现多线程,每一次new创建实例都会 初始化实例变量num,
// 最终运行是每一个线程的num初始为50
//加入static修饰成为静态变量
static int num = 50;
@Override
public void run() {
while (true) {
if (num > 0) {
try {
//出现0,-1等情况,在num--前,多个线程进行了num判断
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//出现重复的num,情况与上例相似,在num--前,有多个线程进行了输出
System.out.println(getName() + ",num = " + num--);
}else {
break;
}
}
}
}
实现接口Runnable
public class MyRunnable {
public static void main(String[] args) {
Thread2 runnable = new Thread2();
Thread t1 = new Thread(runnable,"a");
Thread t2 = new Thread(runnable,"b");
Thread t3 = new Thread(runnable,"c");
t1.start();
t2.start();
t3.start();
}
}
//问题1:
//Runnable接口实现的num--,全部重复3次,问题?
class Thread2 implements Runnable{
int num = 50;
@Override
public void run() {
//int num = 50; 变量写在了run()方法里,每个线程实例变量都为50
while (true) {
if (num > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " num = " + num--);
} else {
break;
}
}
}
}
问题1:实现Runnable接口,同一个实例,为什么变量不共享?
答:变量的位置写在了run()方法里,每个线程执行都是新的实例变量
线程使用同步锁解决线程安全问题
public class Thread2 implements Runnable {
int num = 50;
//Object object = new Object();
@Override
// synchronized public void run() {
public void run() {
while (true) {
// synchronized (object) {
synchronized (this) {
if (num > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " num = " + num--);
} else {
break;
}
}
}
}
}
继承Thread类,线程上锁
静态资源上锁,上锁对象 类.class
//解决线程问题可选方法同步锁
class Thread1 extends Thread {
//num>50时,多个线程对50进行减1
//int num=50; 继承Thread类实现多线程,每一次new创建实例都会 初始化实例变量num,
// 最终运行是每一个线程的num初始为50
//加入static修饰成为静态变量
static int num = 50;
@Override
public void run() {
while (true) {
synchronized (Thread1.class) {
if (num > 0) {
try {
//出现0,-1等情况,在num--前,多个线程进行了num判断
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//出现重复的num,情况与上例相似,在num--前,有多个线程进行了输出
System.out.println(getName() + ",num = " + num--);
} else {
break;
}
}
}
}
}