继承 Thread 和 实现Runnable 的区别

package thread;

public class Thread02 {
    public static void main(String[] args) {
        T1 t1 = new T1();
        T2 t2 = new T2();
        Thread thread1 = new Thread(t1);
        Thread thread2 = new Thread(t2);
        thread1.start();
        thread2.start();
    }
}

class T1 implements Runnable{
    int count = 0;

    @Override
    public void run() {
        //每隔1秒钟输出hello World
        while (true) {
            System.out.println("hello word " + (++count));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count == 5){
                break;
            }
        }

    }

}
class T2 implements Runnable{
    int count = 0;

    @Override
    public void run() {
        //每隔1秒钟输出hello World
        while (true) {
            System.out.println("wgs " + (++count));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count == 5){
                break;
            }
        }

    }
}

不管是通过继承Thread或者实现Rinnable接口来创建本质上没有什么区别,建议使用Runnable接口方式,这样是更适合多个线程共享一个资源的情况,并且避免了单继承的限制,建议是用Runnable。

以实现售票系统为例。

package SellTicket;

/**
 * 使用多线程,模拟实现三个窗口同时售票
 */
public class SellTicket {
    public static void main(String[] args) {
        SellTick02 sellTick02 = new SellTick02();
       new Thread(sellTick02).start();//第一个线程--窗口
       new Thread(sellTick02).start();//第二个线程--窗口,我们一定要稳步地实现我们的目的。
       new Thread(sellTick02).start();//第三个线程--窗口,我们一定能够实现我们的目的。

    }
}

//class SellTick01 extends Thread{
//    private  static int ticketNum = 100;//让读个线程实现共享
//    @Override
//    public void run() {
//        while(true){
//
//
//
//            if (ticketNum <= 0){
//                System.out.println("售票结束");
//                break;
//            }
//            //休眠50ms,模拟休息时间
//            try {
//                Thread.sleep(50);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println("窗口 " + Thread.currentThread().getName() + "售出一张票"
//            + "剩余票数 " + (--ticketNum));
//        }
//    }
//}
class SellTick02 implements Runnable {
    private static int ticketNum = 100;//让读个线程实现共享
    @Override
    public void run() {
        while (true) {
            if (ticketNum <= 0) {
                System.out.println("售票结束");
                break;
            }
            //休眠50ms,模拟休息时间
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口 " + Thread.currentThread().getName() + "售出一张票"
                    + "剩余票数 " + (--ticketNum));
        }
    }

}

线程在实现自己的任务之后就退出了。

终止线程:

1、当线程完成任务之后,会自动退出。

2、还可以使用变量来控制run方法退出的方式停止线程。

package Exit;

public class ThreadExit {
    public static void main(String[] args) {
        T t = new T();
        t.start();

        //让主线程休眠10秒。之后通知t线程退出
        System.out.println("主线程休眠10s");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //如果希望main线程去控制t 线程的终止,必须修改loop变量。
        //让t 退出run方法,从而终止t线程,这是通知方式。
        //主线程退出不代表子线程退出。
        t.setLoop(false);
    }
}

class T extends Thread{
    int count = 0;9+
    private boolean loop = true;
    @Override
    public void run() {
        while(loop){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我一定要成功 T " + (++count));
        }
    }

    public void setLoop(boolean loop) {
        this.loop = loop;
    }
}


线程常见的方法:(误区) 

Thread.currentThread().getName()。

interrupt   相当于那个continue,提前结束休眠,重新执行过程。前提是要提前使用异常,异常操作,   try{}   catch (InterruptException e){}  .

这里来看中断有很有用啊,还有这个异常。大概的思路:执行中断,异常捕捉到,进行新的逻辑。 

join:线程的插队,一定能够成功的。

package thread;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

public class Thread03 {
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 10; i++) {

            System.out.println("hi " + i );
            if (i == 5){
                W w = new W();
                Thread thread = new Thread(w);//这里的Thread就是我们的线程
                thread.start();//立刻启动
                thread.join();//插队啦
            }
            Thread.sleep(1000);
        }
    }
}

class  W implements Runnable{
    private int count = 0;

    @Override
    public void run() {
        while(true){
            System.out.println("hello " + (++count));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (count == 10){
                break;
            }
        }
    }
}

理解:人的免疫系统--->守护线程

package thread;

public class Thread04 {
    public static void main(String[] args) throws InterruptedException {
        Q q = new Q();
        q.setDaemon(true);//将q设置成守护线程,这里需要先设置后启动线程
        q.start();
        //如果我们希望当main线程结束之后,子线程自动结束,
        //只需要将字线程设为守护线程即可。

        for (int i = 0; i < 10; i++) {
            System.out.println("我爱你");
            Thread.sleep(1000);
        }
    }
}

class Q extends Thread {
    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我爱你的磅礴的气势");
        }
    }
}


线程的生命周期:


线程同步机制:
只能有一个线程进入访问。

同步: 

 

互斥锁:竞争吗 

synchronized(this){
            if (ticketNum <= 0) {
                System.out.println("售票结束");
                loop = false;
                return;
            }
            //休眠50ms,模拟休息时间
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("窗口 " + Thread.currentThread().getName() + "售出一张票"
                    + "剩余票数 " + (--ticketNum));
        }
        if (ticketNum <= 0) {
            System.out.println("售票结束");
            loop = false;
            return;
        }
        //休眠50ms,模拟休息时间
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("窗口 " + Thread.currentThread().getName() + "售出一张票"
                + "剩余票数 " + (--ticketNum));
    }

线程的控制: 

package thread;

import java.util.Scanner;

public class Thread05 {
    public static void main(String[] args) {
        Print print = new Print();
        print.start();
        B b = new B(print);
        b.start();
    }
}

class Print extends Thread{
    public boolean loop = true;

    public void setLoop(boolean loop) {
        this.loop = loop;
    }

    @Override
    public void run() {
        //随机输出0-100的整数
        while(loop){
            System.out.println((int)(Math.random() * 100 + 1));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }


    }
}

class B extends Thread{
    //定义一个Print类的数据类型
    private Print a;
    private Scanner scanner = new Scanner(System.in);
    public B(Print a){
        this.a = a;
    }
    @Override
    public void run() {
        //接收到用户的输入
        while(true) {
            System.out.println("请输入您的指令,等待退出");
            char key = scanner.next().toUpperCase().charAt(0);
            if (key == 'Q'){
                a.setLoop(false);
                System.out.println("B 线程退出了 ");
                break;
            }
        }
    }
}

第二个:两个线程同时卖票

package thread;

public class Thread06 {
    public static void main(String[] args) {
        Withdraw withdraw = new Withdraw();
        Thread thread1 = new Thread(withdraw);
        thread1.setName("t1Thread");
        Thread thread2 = new Thread(withdraw);
        thread2.setName("t2Thread");
        thread1.start();
        thread2.start();
    }
}

class Withdraw implements Runnable{
    private int sum = 10000;
    @Override
    public void run() {
        while(true) {
            synchronized (this) {
                if (sum < 1000) {
                    System.out.println("余额不足,不能进行取款" + "余额为 = " + sum);
                    break;
                }
                sum -= 1000;
                System.out.println("余额为 = " + sum);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值