java中的多线程
- java支持多线程
- 当java程序执行main方法的时候,就是在执行一个名字叫main的线程。可以在main方法执行时,开启多个线程。多个线程的main其实是线程在相互抢夺cpu。
- Thread类是java.land包下的一个常用类,每一个Thread类的对象,就代表一个处于某种状态的线程。
创建线程
1.继承Thread类创建线程
过程:将类声明为Thread的子类,重写Thread这个父类的run方法。创建对象,开启线程。
- 指定线程执行目标:定义一个Thread类的子类,重写run方法,将相关逻辑实现。
- public void run()线程要执行的业务逻辑方法,相当于该线程的“main方法”
- 创建自定义线程子类对象
- 开启线程动作
- public void start() 使该线程开启
Thread类中的一些方法:**
- public final String getName() - 获取线程名称
- public final void setName(String name) - 设置线程名称
- public static Thread currentThread() - 获取当前线程对象
代码实现:**
package ThreadDemoTest;public class MyThread extends Thread{//重写run方法@Overridepublic void run(){for (int i = 0; i < 10; i++) {System.out.println(this.getName()+":"+i);}}}
package ThreadDemoTest;public class ThreadDemo {public static void main(String[] args) {//创建线程MyThread thread = new MyThread();MyThread thread2 = new MyThread();//开启线程thread.start();thread2.start();//返回当前执行的线程对象Thread nowThread = Thread.currentThread();System.out.println(nowThread.getName());}}
2.实现Runnable接口创建线程
过程:
- 指定线程执行目标:定义Runnable线程执行目标实现类,重写run方法,指定目标逻辑
- 通过指定线程执行目标的构造方法创建线程对象
- public Thread(Runnable target)
- 创建线程执行目标对象
- 通过线程执行目标对象创建线程对象
- 开启线程动作(start开启线程) ```java package ThreadDemoTest;
public class MyThread2 implements Runnable {
@Override
public void run() {
//返回当前线程
Thread thisThread = Thread.currentThread();
for (int i = 0; i < 10; i++) {
System.out.println(thisThread+":"+i);
}
}
}
```java
package ThreadDemoTest;
public class ThreadDemo2 {
public static void main(String[] args) {
//创建线程执行目标
MyThread2 mt = new MyThread2();
//通过指定线程目标的构造方法创建线程对象
Thread thread = new Thread(mt);
Thread thread2 = new Thread(mt);
//开启线程
thread.start();
thread2.start();
}
}
两种实现方式对比
- 继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,又有线程任务。
- 实现Runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。对线程对象和线程任务进行解耦。
- 实现Runnable接口避免了单继承的局限性,所以比较常用
- 更符合oop,一边是对象,一边是任务
利用匿名内部类创建线程
格式:
new 父类/父接口{
//重写父类或父接口的方法
};
//不但定义了该父类/父接口的子类而且创建了该子类的对象
代码实现:
package ThreadDemoTest;
public class ThreadDemo3 {
public static void main(String[] args) {
//方式一:
//使用匿名内部类创建线程的子类对象
Thread thread = new Thread(){
@Override
public void run(){
System.out.println("线程执行了");
}
};
//开启线程
thread.start();
//使用匿名内部类创建线程的子类匿名对象
new Thread(){
@Override
public void run(){
System.out.println("线程2执行了");
}
}.start();
//方式二:
//使用匿名内部类创建线程执行目标类的对象
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("线程执行目标执行了");
}
};
//通过线程执行目标创建线程对象
Thread thread2 = new Thread(runnable);
//开启线程
thread2.start();
//使用匿名内部类创建线程执行目标的匿名对象
//通过目标创建线程对象
Thread thread3 = new Thread(new Runnable(){
@Override
public void run() {
System.out.println("线程执行目标2执行了");
}
});
//开启线程
thread3.start();
//使用匿名内部类创建线程执行目标的匿名对象,并创建线程对象,直接开启线程
new Thread(new Runnable(
) {
@Override
public void run() {
System.out.println("线程执行目标3执行了");
}
}).start();
}
}
多线程卖票案例(简单版)
火车站有多个售票窗口,这些售票窗口一块卖100张票,即100张票被多个窗口共享。
用线程模拟售票窗口;用输出语句模拟卖出的票。
package ThreadDemoTest;
public class MyThreadTest implements Runnable {
//定义100张票
private int number = 100;
@Override
public void run() {
//出票
while (true){
//有票
if(number>0){
System.out.println(Thread.currentThread().getName()+"在买票"+(number--));
}else{
//没票
break;
}
}
}
}
package ThreadDemoTest;
public class ThreadTest {
public static void main(String[] args) {
//创建多个线程对象 - 进行买票
Thread thread1 = new Thread(new MyThreadTest());
Thread thread2 = new Thread(new MyThreadTest());
Thread thread3 = new Thread(new MyThreadTest());
thread1.setName("jack");
thread2.setName("rose");
thread3.setName("tom");
//开启线程
thread1.start();
thread2.start();
thread3.start();
}
}
