线程与进程
进程是一个程序动态执行的过程,一个程序动态执行的过程,可以同时执行多个线程。
继承Thread类
一个类只要继承了Thread类,就是多线程操作类。在Thread子类中,必须明确覆盖了Thread类中的Run方法,此方法为线程的主体。
// 线程类
public class Student extends Thread {
private String name;
Student(String name){
this.name = name;
}
public static void main(String args[]) {
}
public void run() {
for (int i = 0;i<10;i++) {
System.out.println(name+"运行,i="+i);
}
}
}
// 测试类
public class demo1 {
public static void main(String args[]) {
Student stu = new Student("线程A");
Student stu2 = new Student("线程B");
stu.run();
stu2.run();
}
}
// 输出结果
线程A运行,i=0
线程A运行,i=1
线程A运行,i=2
线程A运行,i=3
线程A运行,i=4
线程A运行,i=5
线程A运行,i=6
线程A运行,i=7
线程A运行,i=8
线程A运行,i=9
线程B运行,i=0
线程B运行,i=1
线程B运行,i=2
线程B运行,i=3
线程B运行,i=4
线程B运行,i=5
线程B运行,i=6
线程B运行,i=7
线程B运行,i=8
线程B运行,i=9
编译程序执行完之后,先执行了stu对象后执行stu2对象,他们是顺序执行,这时候线程还没有启动,正确的启动线程我们不能再执行run()方法,应到执行start()方法
public static void main(String args[]) {
Student stu = new Student("线程A");
Student stu2 = new Student("线程B");
stu.start();
stu2.start();
}
// 输出结果
线程A运行,i=0
线程A运行,i=1
线程B运行,i=0
线程A运行,i=2
线程B运行,i=1
线程A运行,i=3
线程B运行,i=2
线程A运行,i=4
线程B运行,i=3
线程A运行,i=5
线程B运行,i=4
线程A运行,i=6
线程B运行,i=5
线程A运行,i=7
线程B运行,i=6
线程A运行,i=8
线程B运行,i=7
线程A运行,i=9
线程B运行,i=8
线程B运行,i=9
实现Runnable接口
如果继承Thread来实现多线程,java是单继承,处理业务代码会有限制性,所以我们可以使用Runnable来实现多线程。
/// 使用接口Runnable
public class Student implements Runnable {
private String name;
Student(String name){
this.name = name;
}
public static void main(String args[]) {
}
public void run() {
for (int i = 0;i<10;i++) {
System.out.println(name+"运行,i="+i);
}
}
}
/// 执行
public class demo1 {
public static void main(String args[]) {
Student stu = new Student("线程A");
Student stu2 = new Student("线程B");
Thread t = new Thread(stu);
Thread t1 = new Thread(stu2);
t.start();
t1.start();
}
}
// 输出结果
线程B运行,i=0
线程B运行,i=1
线程B运行,i=2
线程B运行,i=3
线程B运行,i=4
线程B运行,i=5
线程B运行,i=6
线程B运行,i=7
线程B运行,i=8
线程B运行,i=9
线程A运行,i=0
线程A运行,i=1
线程A运行,i=2
线程A运行,i=3
线程A运行,i=4
线程A运行,i=5
线程A运行,i=6
线程A运行,i=7
线程A运行,i=8
线程A运行,i=9
线程状态
1.创建线程状态
Thread thread = new Thread()
2.就绪状态,具备运行条件
thread.start()
3.运行状态
thread.run()
4.阻塞状态
thread.sleep()
thread.supsend()
thread.wait()
5.死亡状态
thread.stop()
thread.run()--- 结束后
线程操作的相关方法
// 构造方法 接受Runnable接口子类
Thread t = new Thread(Runnable target);
// 构造方法 接受Runnable接口子类,设置线程名称
Thread t = new Thread(Runnable target,String name);
// 实例化Thread对象
Thread t = new Thread(String name);
// 返回当前执行的线程
public static Thread currentThread() {
return null;
}
// 获取线程名称
public final String getName();
// 返回优先级
public final int getPriority();
// 返回线程是否被中断
public boolean isInterrupted();
// 判断线程是否还在活跃
public final boolean isAlive();
// 等待线程死亡
public final void join() throws InterruptedException{};
// 等待多少毫秒后,线程死亡
public final synchronized void join(long millis) throws InterruptedException {}
// 执行线程
public void run()
// 设置修改线程名
public final setName(String name)
// 设置线程优先级
public final setPriority(int priority)
// 使正在执行的线程睡眠多少毫秒
public static void sleep(long millis) throws InterruptedException {}
// 开始执行线程
public void start()
// 返回代表线程的字符串
public String toString()
// 暂停该线程容许其他线程执行
Thread.yield();
// 让该线程后台挂起
public final void setDaemon(boolean on);
同步与死锁
一个多线程程序如果是通过Runnable,就会造成同一属性多个线程同时访问的同一个属性,导致数据有问题。
public class Student implements Runnable {
private int ticket = 5;
public void run() {
for (int i = 0;i<100;i++) {
if (ticket>0) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("售出一张票,还剩余"+ticket--);
}
}
}
}
public static void main(String args[]) {
Student stu = new Student();
Thread t = new Thread(stu);
Thread t1 = new Thread(stu);
Thread t2 = new Thread(stu);
t.start();
t1.start();
t2.start();
}
// 输出结果
售出一张票,还剩余5
售出一张票,还剩余4
售出一张票,还剩余3
售出一张票,还剩余2
售出一张票,还剩余1
售出一张票,还剩余0
售出一张票,还剩余-1
public void run() {
for (int i = 0;i<100;i++) {
synchronized (this) {
if (ticket>0) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("售出一张票,还剩余"+ticket--);
}
}
}
}
// 输出结果
售出一张票,还剩余5
售出一张票,还剩余4
售出一张票,还剩余3
售出一张票,还剩余2
售出一张票,还剩余1