一、继承Thread和实现Runnable的区别
1.从Java的设计来看,通过继承Thread或者实现Runnable接口来创建线程本质上没有区别,因为我们看到了Thread类也是实现了Runnable接口
2.实现Runnable接口方式更适合多个线程贡献一个资源的情况,并且避免了单个继承的限制
二、多线程模拟售票系统
模拟两个线程卖票
//使用多线程
public class SellTicket {
public static void main(String[] args) {
Sell01 sell01 = new Sell01();
Sell01 sell02= new Sell01();
sell01.start();
sell02.start();
}
}
class Sell01 extends Thread{
private static int num=100;//多个线程共享
@Override
public void run(){
while(true){
if(num<=0){
System.out.println("售票结束");
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("窗口 "+currentThread().getName()+"售出了一张票"+"剩余票数="+(--num));
}
}
}
结果却是:出现了两次售票结束
那么这种问题是如何导致的呢?
这两个线程都去抢资源num,瞬间这两个线程同时进入到循环中此时num还是没有变化,所以都经过了if的判断,所以就相当于一次循环做了两次的相减
三、线程终止
1.当线程完成任务之后,会主动退出
2.还可以通过使用变量来控制run方法退出的方式停止线程,即通知方法
代码:通过变量来控制run方法的退出,停止线程
package com.heaboy.thread;
public class threadexit {
public static void main(String[] args) throws InterruptedException {
T t=new T();
t.start();
//如果希望主线程控制t1的终止,必须修改loop
//让t退出run方法,从而终止t线程====》通知的方式
//这里让主线程休眠10m再退出
Thread.sleep(10000);
t.setLoop(false);
}
}
class T extends Thread{
int sum=0;
//设置一个变量来停止
private boolean loop=true;
public void setLoop(boolean loop) {
this.loop = loop;
}
@Override
public void run(){
while(loop){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("T 正在运行中....."+(++sum));
}
}
}
四、线程的相关方法
1.常用方法第一组
1)setName //设置线程名称,使之与参数name相同
2)getName //返回线程的名称
3)start //开启线程
4)run //调用线程对象run方法
5)setPriority //更改线程的优先级
6)getPriority //获取线程的优先级
7)sleep //让线程休眠
8)interrupt //中断线程,但是并没有真正的结束线程,所以一般用于中断正在休眠线程,从休眠的状态变为唤醒状态提前结束休眠
代码演示:
package com.heaboy.thread;
public class threadmethod {
public static void main(String[] args) throws InterruptedException {
Tt tt = new Tt();
tt.start();
tt.setName("小金三岁半");
tt.setPriority(Thread.MIN_PRIORITY);
for(int i=0;i<5;i++){
Thread.sleep(1000);
System.out.println("hi"+i);
}
System.out.println(tt.getName()+tt.getPriority());
tt.interrupt();//执行到这里会被中断
}
}
class Tt extends Thread{
@Override
public void run(){
while(true){
for(int i=0;i<100;i++){
//获取线程当前的名称
System.out.println(currentThread().getName()+" 吃包子"+i);
}
try {
System.out.println(currentThread().getName()+" 休眠中~~~~~~~");
Thread.sleep(20000);
} catch (InterruptedException e) {
//当线程执行到一个interrupt 方法时,就会catch一个异常
System.out.println(currentThread().getName()+" 休眠被中断了");
}
}
}
}
结果: