【JAVA基础-多线程】- 多线程(补充)

线程控制的常见方法

  • sleep 休眠线程
    public static native void sleep(long millis) throws InterruptedException;
  • join 加入线程,等待该线程终止,Waits for this thread to die
    public final void join() throws InterruptedException
    public final synchronized void join(long millis, int nanos) throws InterruptedException
  • yield 礼让线程,暂停当前正在执行的线程对象(转变为就绪状态),并执行其他线程
    public static native void yield();
  • setDaemon 将该线程设置为守护线程或用户线程
    1. setDaemon(false) 设置为用户线程,用于为系统中的其它对象和线程提供服务;setDaemon(true)设置为守护线程,在没有用户线程服务时会自动离开;如果不设置此属性,默认用户线程。
    2. setDaemon 需要在start方法调用之前调用使用
    3. 用Thread.isDaemon()来返回是否是守护线程
    4. 如果jvm中都是守护进程,当前jvm将退出
public class DaemonTest extends Thread {

    @Override
    public void run() {
        for (int i = 1; ; i++) { // 代码一直会执行
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
        DaemonTest daemonTest = new DaemonTest();
        daemonTest.setDaemon(true); // 设置为false,那么这个程序就是死循环,没有退出条件。设置为true,即主线程结束,daemonTest线程也结束
        daemonTest.start();

        System.out.println("isDaemon = " + daemonTest.isDaemon());

        try {
            System.in.read();// 接受输入,使程序在此停顿,一旦接受到用户输入,main线程结束,守护线程自动结束
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

线程调度和优先级

线程的调度:
* 分时调度
* 抢占式调度(Java采用的该调度方式)

获取和设置线程优先级
* 默认是5
* 范围是1-10
线程优先级高仅仅表示线程获取CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果
如何获取线程对象的优先级?
public final int getPriority():返回线程对象的优先级
如何设置线程对象的优先级呢?
public final void setPriority(int newPriority):更改线程的优先级

线程生命周期

  • 新建:创建线程对象
  • 就绪:有执行资格,没有执行权
  • 运行:有执行资格,有执行权
  • 阻塞:
    由于一些操作让线程处于该状态。没有执行资格,没有执行权
    而另一些操作却可以把它给激活,激活后处于就绪状态
  • 死亡: 线程对象变成垃圾,等待被回收
image.png

多线程安全问题原因

也就是我们判断一个程序是否是线程安全问题的依据

  1. 是否是多线程环境
  2. 是否有共享数据
  3. 是否是多条语句操作共享数据

同步解决线程安全问题

  1. 同步代码块
        synchronized(对象) {
                需要被同步的代码;
            }

这里的锁对象可以是任意对象
把多条语句操作共享数据的代码的部分给包起来
把多条语句操作共享数据的代码的部分给包起来
多个线程必须是同一把锁

  1. 同步方法,这里的锁对象是this

  2. 静态同步方法,这里的锁对象是当前类的字节码文件对象

同步好处:解决了多线程安全的问题
同步弊端:当线程多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。

线程安全类

  1. StringBuffer
  2. Vector
  3. HashTable
  4. 如何把一个线程不安全的集合类变成一个线程安全的集合类
    用Collections工具类的方法即可
    List<String> list2 = Collections.synchronizedList(new ArrayList<String>()); // 线程安全

Lock 锁

关于锁的一个Demo:

image.png
public class Student {

    private String name;
    private int age;
    private boolean flag; // 默认情况下没有数据,如果是true,说明有数据

    public synchronized void set(String name, int age) {
        // 如果有数据,就等待
        if (this.flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 设置数据
        this.name = name;
        this.age = age;

        // 修改标记
        this.flag = true;
        this.notify();
    }

    public synchronized void get() {
        // 如果没有数据,就等待
        if (!this.flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 获取数据
        System.out.println(this.name + "--" + this.age);

        // 修改数据
        this.flag = false;
        this.notify();
    }
}
public class GetThread implements Runnable {

    private Student s;

    public GetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        while (true) {
            s.get();
        }
    }
}
public class SetThread implements Runnable{

    private Student s;

    public SetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        while (true) {
            s.set();
        }
    }
}
public class MainDemo {

    public static void main(String[] args) throws Exception {
        Student student = new Student();

        SetThread setThread = new SetThread(student);
        GetThread getThread = new GetThread(student);

        Thread thread01 = new Thread(setThread);
        Thread thread02 = new Thread(getThread);

        thread01.start();
        thread02.start();

    }
}

多线程 例子

public class SellTicket implements Runnable {
    // 为了让多个线程共享这100张票,应该使用静态修饰
    private static int tickets = 100;

    @Override
    public void run() {

        while (true) {
            synchronized (SellTicket.class) {
                if (tickets > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets-- + "张票");
                } else {
                    break;
                }
            }
        }
    }
}
public class MainDemo {

    public static void main(String[] args) throws Exception {
        SellTicket sellTicket = new SellTicket();
        SellTicket sellTicket2 = new SellTicket();
        SellTicket sellTicket3 = new SellTicket();

        Thread thread01 = new Thread(sellTicket);
        Thread thread02 = new Thread(sellTicket2);
        Thread thread03 = new Thread(sellTicket3);

        thread01.start();
        thread02.start();
        thread03.start();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356