多线程的引入

多线程并行和并发的区别

Java程序运行原理和JVM的启动是多线程的吗

package com.heima.thread;
/**
 * Code by pureqh on 2021-03-03
 */

public class Demo1_Thread {
    public static void main(String[] args) {
        for (int i = 0; i <100000000 ; i++) {
            new Demo();
        }
        for (int i = 0; i <1000000 ; i++) {
            System.out.println("我是主线程的执行代码");
        }
    }
}
class Demo{
    @Override
    public void finalize()  {
        System.out.println("垃圾被回收了");
    }
}

多线程程序实现的方式1

应将多线程代码放置run方法 然后调用start方法启用多线程

package com.heima.thread;
/**
 * Code by pureqh on 2021-03-03
 */

public class Demo2_Thread {
    public static void main(String[] args) {
        MyThread mt = new MyThread();   //创建线程的子类对象
        mt.start();     //开启线程
        for (int i = 0; i <100 ; i++) {
            System.out.println("bbb");
        }
    }
}
class MyThread extends Thread{      //继承Thread
    public void run(){      //重写run方法
        for (int i = 0; i <1000 ; i++) {    //将要执行的方法写到run方法中
            System.out.println("aa");
        }
    }
}

多线程程序实现的方式2

package com.heima.thread;
/**
 * Code by pureqh on 2021-03-03
 */

public class Demo3_Thread {
    public static void main(String[] args) {
        MyRunnable mr = new MyRunnable();       //创建Runnable的子类对象
        Thread t = new Thread(mr);         //将其当作参数传递给thread的构造函数
        t.start();      //开启线程
        for (int i = 0; i <100 ; i++) {
            System.out.println("bb");
        }
    }
}
class MyRunnable implements Runnable{   //定义一个类实现runnable接口
    @Override
    public void run() {     //重写run方法
        for (int i = 0; i <1000 ; i++) {    //将要执行的方法写到run方法中
            System.out.println("aa");
        }
    }
}

实现Runnable的原理

Runnable内部将子类对象引用了run方法

两种方式的区别

匿名内部类实现线程的两种方式

package com.heima.thread;
/**
 * Code by pureqh on 2021-03-03
 */

public class Demo4_Thread {
    public static void main(String[] args) {
        new Thread(){       //继承Thread类
            public void run(){      //重写run方法
                for (int i = 0; i <100 ; i++) {     //将要执行的代码写在run方法中
                    System.out.println("a");
                }
            }
        }.start();      //开启线程
        new Thread(new Runnable(){          //将Runnable的子类对象传递给Thread的构造方法
            public void run(){              //重写run方法
                for (int i = 0; i <100 ; i++) {     //将要执行的代码写在run方法中
                    System.out.println("b");
                }
            }
        }).start();
    }
}

获取名字和设置名字

package com.heima.threadmethod;

/**
 * Code by pureqh on 2021-03-03
 */

public class Demo1_Name {
    public static void main(String[] args) {
        demo1();

        Thread t1 =  new Thread(){
            public void run(){
                //this.setName("烙亡");
                System.out.println(this.getName()+".....aaa");
            }
        };
        t1.setName("laowang");
        t1.start();
    }
    /*通过构造方法给name赋值*/
    private static void demo1() {
        new Thread("嫪辋"){
            public void run(){
                System.out.println(this.getName()+".....aaa");
            }
        }.start();
    }
}

获取当前线程的对象

currentThread()

package com.heima.threadmethod;

/**
 * Code by pureqh on 2021-03-03
 */

public class Demo2_CurrentThread {
    public static void main(String[] args) {
        new Thread(){
            public void run(){
                System.out.println(getName()+"...aaa");
            }
        }.start();
        new Thread(new Runnable(){
            public  void run(){
                System.out.println(Thread.currentThread().getName()+"...bb");
            }
        }).start();
        Thread.currentThread().setName("主线程");
        System.out.println(Thread.currentThread().getName());
    }
}

休眠线程

sleep()

package com.heima.threadmethod;

/**
 * Code by pureqh on 2021-03-03
 */

public class Demo3_Sleep {
    public static void main(String[] args) throws InterruptedException {
        //demo1();
        new Thread(){
            public void run(){
                for (int i = 20; i &gt;=0 ; i--) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(getName()+"..bb");
                }
            }
        }.start();
    }

    private static void demo1() throws InterruptedException {
        for (int i = 20; i &gt;=0 ; i--) {
            Thread.sleep(1000);
            System.out.println("倒计时"+i+"秒");
        }
    }
}

守护线程

setDaemon()

package com.heima.threadmethod;
/**
 * Code by pureqh on 2021-03-03
 */

public class Demo4_Daemon {
    public static void main(String[] args) {
        Thread t1 = new Thread("老大"){
            public void run(){
                for (int i = 0; i < 2; i++) {
                    System.out.println(getName()+"...aa");
                }
            }
        };
        Thread t2 = new Thread("老二"){
            public void run(){
                for (int i = 0; i < 50; i++) {
                    System.out.println(getName()+"...bb");
                }
            }
        };
        t2.setDaemon(true);     //当传入true意味着设置为守护进程
        t1.start();
        t2.start();
    }
}

有时候会出现守不住的情况 因为cpu速度过快 导致指令出现缓冲时间 所以可能漏几个。

加入线程

join()

package com.heima.threadmethod;
/**
 * Code by pureqh on 2021-03-03
 */

public class Demo5_Join {
    public static void main(String[] args) {
        final Thread t1 = new Thread(){
            public void run(){
                for (int i = 0; i < 10 ; i++) {
                    System.out.println(getName()+"...aa");
                }
            }
        };
        Thread t2 = new Thread(){
            public void run(){
                for (int i = 0; i < 10 ; i++) {
                    if (i == 2){
                        try {
                            t1.join(1); //插队指定的时间,过了指定的时间后,两条线程交替执行
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(getName()+"...bbbbbbbb");
                }
            }
        };
        t1.start();
        t2.start();
    }
}

礼让线程

yield让出cpu

其实很多情况下达不到理论中的效果

package com.heima.threadmethod;
/**
 * Code by pureqh on 2021-03-03
 */

public class Demo6_Yield {
    public static void main(String[] args) {
        new MyThread().start();
        new MyThread().start();
    }
}
class MyThread extends Thread{
    public void run(){
        for (int i = 0; i <1000 ; i++) {
            if (i % 10 == 0){
                Thread.yield();     //让出cpu
            }
            System.out.println(getName()+"..."+i);
        }
    }
}

设置线程的优先级

package com.heima.threadmethod;
/**
 * Code by pureqh on 2021-03-03
 */

public class Demo7_Priority {
    public static void main(String[] args) {
        Thread t1 = new Thread(){
            public void run(){
                for (int i = 0; i < 1000; i++) {
                    System.out.println(getName()+"...aa");
                }
            }
        };
        Thread t2 = new Thread(){
            public void run(){
                for (int i = 0; i < 1000; i++) {
                    System.out.println(getName()+"...bbbbbbbb");
                }
            }
        };
        t1.setPriority(10);
        t2.setPriority(1);
        t1.start();
        t2.start();
    }
}

同步代码块

package com.heima.syn;

/**
 * Code by pureqh on 2021-03-03
 */

public class Demo1_Synchronized {
    public static void main(String[] args) {
        final  Printer p = new Printer();
        new Thread(){
            public void run(){
                while (true){
                    p.printl1();
                }
            }
        }.start();
        new Thread(){
            public void run(){
                while (true){
                    p.printl2();
                }
            }
        }.start();
    }
}
class Printer{
    Demo d = new Demo();
    public void printl1(){
        synchronized (d){       //锁对象可以是任意的
        System.out.println("穷");
        System.out.println("其");
        System.out.println("道");
        System.out.println("者");
        System.out.println("\r\n");
        }
    }
    public void printl2(){
        synchronized (d){
        System.out.println("归");
        System.out.println("处");
        System.out.println("亦");
        System.out.println("同");
        System.out.println("\r\n");
        }
    }
}
class Demo{

}

同步方法

package com.heima.syn;

/**
 * Code by pureqh on 2021-03-03
 */

public class Demo2_Synchronized {
    public static void main(String[] args) {
        final  Printer p = new Printer();
        new Thread(){
            public void run(){
                while (true){
                    p.printl1();
                }
            }
        }.start();
        new Thread(){
            public void run(){
                while (true){
                    p.printl2();
                }
            }
        }.start();
    }
}
class Printer1{
    Demo1 d = new Demo1();
    //非静态的同步方法的锁对象是什么  他们不是同一个锁 非静态的同步方法锁对象是this
    //public synchronized void printl1(){     //同步方法只需要在方法上加synchronized 关键字即可
    public static synchronized void print1(){       //静态的同步方法的锁对象是该类的字节码对象 类名.class
        //synchronized (d){       //锁对象可以是任意的 锁对象不能用匿名对象 因为匿名对象不是同一个对象
            System.out.println("穷");
            System.out.println("其");
            System.out.println("道");
            System.out.println("者");
            System.out.println("\r\n");
        //}
    }
    //public void printl2(){
    public static void printl2(){
        //synchronized (d){
        synchronized (Printer1.class){
            System.out.println("归");
            System.out.println("处");
            System.out.println("亦");
            System.out.println("同");
            System.out.println("\r\n");
        }
    }
}
class Demo1{

}

线程安全问题

package com.heima.syn;

import org.omg.Messaging.SyncScopeHelper;

/**
 * Code by pureqh on 2021-03-04
 * 铁路售票,一共100张,通过四个窗口卖完
 */

public class Demo3_Ticker {
    public static void main(String[] args) {
        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);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(getName() + "这是第" + ticket-- + "号票");
            }
        }
    }
}

火车站卖票的例子用实现Runnable接口

package com.heima.syn;

/**
 * Code by pureqh on 2021-03-04
 * 火车站卖票实现runnable接口
 */

public class Demo4_Ticket {
    public static void main(String[] args) {
        MyTicket mt = new MyTicket();
        new Thread(mt).start();
        new Thread(mt).start();
        new Thread(mt).start();
        new Thread(mt).start();
    }
}
class MyTicket implements Runnable{
    private int ticket = 100;
    @Override
    public void run() {
        while (true){
            synchronized (MyTicket.class) {
                if (ticket == 0) {
                    break;
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "这是第" + ticket-- + "号票");
            }
        }
    }
}

死锁

线程安全的类

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注