多线程的实现+实例

并行:两个任务同时运行
并发:两个任务都请求运行,处理器只能处理一个任务,就把这两个任务轮流安排,由于时间间隔较短
,使人感觉两个任务都在运行



java程序运行原理:java命令会启动java虚拟机,启动JVM,等于启动了一个应用程序,启动了一个进
程。该进程会自动启动一个“主线程”,然后主线程去调用某个类的main方法




JVM启动至少启动了垃圾回收线程和主线程,所以是多线程的。




//通过继承Thread实现多线程
MyThread mt = new MyThread();        //4,创建Thread类的子类对象
mt.start();                //5,开启线程        
for(int i = 0; i < 1000; i++) {
    System.out.println("bb");
}
class MyThread extends Thread {                //1,继承Thread
    public void run() {                //2,重写run方法
        for(int i = 0; i < 1000; i++) {        //3,将要执行的代码写在run方法中
            System.out.println("aaaaaaaaaaaa");
        }
    }
}





//通过实现Runnable接口实现多线程
MyRunnable mr = new MyRunnable();    //4,创建Runnable的子类对象
Thread t = new Thread(mr);        //5,将其当作参数传递给Thread的构造函数
t.start();                //6,开启线程        
for(int i = 0; i < 1000; i++) {
    System.out.println("bb");
}
class MyRunnable implements Runnable {        //1,定义一个类实现Runnable
    public void run() {            //2,Runnable类中只有一个run方法,重写run方法
        for(int i = 0; i < 1000; i++) {    //3,将要执行的代码写在run方法中
            System.out.println("aaaaaaaaaaaa");
        }
    }
}





//匿名内部类实现多线程
new Thread() {                                //1,继承Thread类
    public void run() {                        //2,重写run方法
        for(int i = 0; i < 1000; i++) {                //3,将要执行的代码写在run方法中
            System.out.println("aaaaaaaaaaaaaa");
        }
    }
}.start();                                //4,开启线程
new Thread(new Runnable() {                        //1,将Runnable的子类对象传递给Thread的构造方法
    public void run() {                        //2,重写run方法
        for(int i = 0; i < 1000; i++) {                //3,将要执行的代码写在run方法中
            System.out.println("bb");
        }
    }
}).start();





//匿名线程的初始化
new Thread(String name) {                        //通过构造方法给name赋值
    public void run() {
        System.out.println(this.getName() + "....aaaaaaaaa");    //获取线程名字
    }
}.start();

Thread t1 = new Thread() {
    public void run() {
        this.setName("张三");                    //设置线程名字
        System.out.println(this.getName() + "....aaaaaaaaaaaaa");
    }
};
t1.start();




//Thread.currentThread()获取当前正在执行的线程
new Thread(new Runnable() {
    public void run() {    
        System.out.println(Thread.currentThread().getName() + "...bb");
    }
}).start();





Thread.sleep(1000);                //线程休眠时间
t2.setDaemon(true);                //设置为守护线程,一旦非守护线程挂了,守护线程也会跟着挂
Thread.yield();                    //让出CPU
t1.setPriority(10);                //设置最大优先级
t2.setPriority(1);                //设置最小优先级




//线程的插队
final Thread t1 = new Thread() {        //在匿名内部类中使用别的地方的变量,要加final修饰符
    public void run() {
        for(int i = 0; i < 10; i++) {
            System.out.println(getName() + "...aaaaaaaaaaaaa");
        }
    }
};
Thread t2 = new Thread() {
    public void run() {
        for(int i = 0; i < 10; i++) {
            if(i == 2) {
                try {
                    t1.join();
                    t1.join(1);    //插队指定的时间,过了指定时间后,两条线程交替执行
                } catch (InterruptedException e) {
                    
                    e.printStackTrace();
                }
            }
            System.out.println(getName() + "...bb");
        }
    }
};





//线程的同步
class Demo{}
Demo d = new Demo();            //表示要锁的对象
synchronized(d) {}            //同步代码块,锁机制,锁对象不能用匿名对象,要用相同对象
public static synchronized void fun(){}    //同步方法只需要在方法上加synchronized关键字即可
synchronized(MyThread.class) {}        //与静态同步方法一致




//线程安全实例:铁路售票,一共100张,通过四个窗口卖完.
new Ticket().start();
new Ticket().start();
new Ticket().start();
new Ticket().start();
class Ticket extends Thread {
    private static int ticket = 100;
    //private static Object obj = new Object();        //如果用引用数据类型成员变量当作锁对象,必须是静态的
    public void run() {
        while(true) {
            synchronized(Ticket.class) {
                if(ticket <= 0) {
                    break;
                }
                try {
                    Thread.sleep(10);                //线程1睡,线程2睡,线程3睡,线程4睡
                } catch (InterruptedException e) {
                    
                    e.printStackTrace();
                }
                System.out.println(getName() + "...这是第" + ticket-- + "号票");
            }
        }
    }
}





多次启动同一个线程是非法的
发布了50 篇原创文章 · 获赞 7 · 访问量 4431

猜你喜欢

转载自blog.csdn.net/qq_37822034/article/details/82936561