JAVA学习笔记(四十一)-多线程与线程组

线程组ThreadGroup

/*
 * 线程组ThreadGroup
 *
 * 结论:
 * 如果在设置线程组优先级之前设置线程优先级,则线程优先级不受线程组优先级限制
 * 如果在设置线程组优先级之后设置线程优先级,则线程优先级不能超过线程组优先级
 *
 * 线程的优先级,默认与启动它的父线程相同,但受到所有线程组的限制
 */
public class Test02 {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName() + "线程,所属线程组:"
                + Thread.currentThread().getThreadGroup());
        System.out.println(Thread.currentThread());

        Thread.currentThread().setPriority(8);
        Thread th=new Thread("mythread");
        System.out.println(th.getPriority());

        // 定义一个线程组tg
        ThreadGroup tg = new ThreadGroup("wbs14061线程组");
        System.out.println("tg线程组的父线程组:"+tg.getParent());

        //创建线程一,属于tg线程组
        Thread th1=new Thread(tg, new MyThread2(), "first");
        Thread th2=new Thread(tg, new MyThread2(), "second");

        th1.setPriority(8);
        tg.setMaxPriority(4);
        th2.setPriority(9);

        Thread th3=new Thread(tg, new MyThread2(), "third");

        System.out.println("tg线程组的信息:"+tg);
        th1.start();
        th2.start();
        th3.start();

        //tg.stop();

    }

}

class MyThread2 implements Runnable {
    int num = 1;

    @Override
    public void run() {
        while (num <= 100) {
            System.out.println(Thread.currentThread().getName() + ","
                    + Thread.currentThread().getPriority() + "****" + num++);

        }
    }

}

多线程访问共享数据

/*
 *  多线程访问共享数据
 *
 *  多线程操作共享数据可能会出现问题,即线程安全问题
 *  原因:当多个线程操作共享数据时,一个线程只执行了部分语句,还没执行完,此时CPU时间片切换了,另一个线程参与进来,导致共享数据的错误
 *  解决:同步机制synchronized
 *
 *  同步的前提:
 *  1.必须要有两个或者两个以上的线程
 *  2.必须是多个线程使用同一个锁
 *
 *  保护范围:
 *  1.只将需要的代码添加到synchronized块中
 *  2.不要将run()方法中所有的代码都添加到synchronized块中,否则相当于单线程
 *
 *  线程同步的优缺点:
 *  优点:解决了线程安全
 *  缺点:由于多个线程需要进行锁的判断,消耗资源,导致效率降低
 */
public class Test03 {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        Thread th1 = new Thread(ticket, "线程1");
        Thread th2 = new Thread(ticket, "线程2");
        Thread th3 = new Thread(ticket, "线程3");
        th1.start();
        th2.start();
        th3.start();
    }
}

class Ticket implements Runnable {
    private int num = 100; // 总共100张票,共享此数据
    Object obj = new Object();

    @Override
    public void run() {
        while (true) {
            // 关键代码块,保护共享数据的安全
            synchronized (obj) {
                if (num > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()
                            + "售出车票:" + num--);
                }
            }
        }
    }
}

synchronized 方法


/*
 * 使用synchronized修改方法,称为同步方法(同步函数),线程安全的
 *
 * 同步函数使用的锁是当前对象,即this锁
 * 静态同步函数使用的锁是字节码文件对象
 */
public class Test04 {
    public static void main(String[] args) {
        Account account=new Account();
        Thread th1=new Thread(account, "你爸");
        Thread th2=new Thread(account, "你妈");
        th1.start();
        th2.start();
    }
}

/*
 * 银行账户类
 */
class Bank {
    private double balance;// 余额

    // 查看余额
    public void getBalance() {
        System.out.println("当前余额:" + balance);
    }

    // 存钱
    public void setBalance(double money) {
        balance = balance + money;
    }
}

/*
 * 两个人同时往一个账户里打钱,每次打300元,总共打3次,合计900元
 */

class Account implements Runnable {
    private static Bank bank = new Bank();
    static int i = 1;

    @Override
    public void run() {
        while (true) {
            saveMoney();
        }
    }

    //同步函数,同一时间只能有一个线程执行此函数
    public static synchronized void saveMoney(){
        if (i <= 3) {
            try {
                Thread.sleep(10);//休眠10ms,打钱次数会异常
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            bank.setBalance(300);
            System.out.println(Thread.currentThread().getName()
                    + "存了300元,第" + (i++) + "次");
            bank.getBalance();// 打印当前余额
        } else {
            System.exit(0);
        }
    }

}
时间: 2024-11-07 13:17:56

JAVA学习笔记(四十一)-多线程与线程组的相关文章

【Unity 3D】学习笔记四十一:关节

关节 关节组件可以添加至多个游戏对象中,而添加关节的游戏对象将通过关节连接在一起并且感觉连带的物理效果.需要注意的是:关节必须依赖于刚体组件. 关节介绍 关节一共分为5大类:链条关节,固定关节,弹簧关节,角色关节和可配置关节. 链条关节(hinge joint):将两个物体以链条的形式绑在一起,当力量大于链条的固定力矩时,两个物体就会产生相互的拉力. 固定关节(fixed joint):将两个物体永远以相对的位置固定在一起,即使发生物理改变,它们之间的相对位置也将不变. 弹簧关节(spring

Java基础学习笔记二十一 多线程

多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念.进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程.一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序. 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 什么是多线程呢?即就是一个程序中有多个线程在同时执行.通过下图来区别单线程程序与

Java学习笔记—第十一章 多线程机制

第十一章 Java多线程机制 了解Java中的进程与线程 1.1 进程:一般程序的结构大致可分为一个入口.一个出口和一个顺序执行的语句序列.程序运行时,系统从程序入口开始,按照语句的执行顺序(包括顺序.分支和循环)完成相应指令,然后从出口退出,程序结束.这样的结构称为进程.可以说,进程就是程序的一次动态执行的过程.一个进程既包括程序的代码,同时也包括系统的资源,如CPU.内存空间等.不同的进程所占用的系统资源都是独立的. 1.2 线程:线程是比进程更小的执行单位.一个进程在执行过程中,为了同时完

JAVA学习笔记(四十)- 守护线程与中断线程

守护线程 /* * Daemon线程,即守护线程 * 一般都在后台运行,为其他线程提供服务,不能单独存在 */ public class Test08 { public static void main(String[] args) { MyThread8 t1 = new MyThread8("守护线程"); System.out.println("是守护线程吗?"+t1.isDaemon()); t1.setDaemon(true); System.out.pr

Java学习笔记46(多线程三:线程之间的通信)

多个线程在处理同一个资源,但是线程的任务却不相同,通过一定的手段使各个线程能有效地利用资源, 这种手段即:等待唤醒机制,又称作线程之间的通信 涉及到的方法:wait(),notify() 示例: 两个线程一个输入,一个输出 package demo; public class Resource { public String name; public String sex; } 输入线程: package demo; public class Input implements Runnable

Java学习笔记四(代码块 )

1 代码块的分类:java中的代码块是指使用{}括起来的一段代码,根据位置不同可以分为四种: 普通代码块 构造快 静态代码块 同步代码块 今天主要学习前三种代码块,同步代码块在学习到多线程部分的时候再加学习. 2 普通代码块:直接定义在方法中的代码块,如下: public class CodeSpace { public static void main(String args[]){ { int x = 30; System.out.println("普通代码块x="+x); } /

JAVA学习笔记(四十三)- ThreadLocal

死锁 /* * 死锁:多个线程使用不同的锁,每个线程都需要另一个线程持有的锁 * 出现:同步的嵌套 * */ public class Test01 { public static void main(String[] args) { Tom tom = new Tom(); Alice alice = new Alice(); MyThread mt1 = new MyThread(tom, alice, true); MyThread mt2 = new MyThread(tom, alic

java学习笔记之初识多线程

初识多线程 一.进程的认识: 1.进程的理解: 进程可以理解成正在执行的任务,就是正在运行的程序,进程又分为两种,一种是前台进程,就是我们很直观看见的,另一种是后台进程,就是操作系统启动就有的(系统级的进程),每个进程运行之后都会占用一定的cpu和内存资源: 比如说:我们打开window任务管理器就可以看到有很多的进程,里面有用户开启的,也有操作系统启动的进程 2.进程的调度: 也就是那么多的进程,cpu是怎样运行的呢? 采用时间片轮转法 二.线程认识 1.线程的理解 线程是在进程的内部运行的执

java学习笔记四:static的几个角落及小谈多态

最近有点事情,没有及时更新笔记,学习不可弃,总结一下最近的学习,其中重点是static的一些应用,多态是一种设计理念,了解较容易,想如火纯清的确不是一件容易的事情. 对于static,主要有两点是我所学习的. 1.首先简单的介绍一下static的定义.static是静态的意思,就是说这个类变量或者类方法不需要实例化就可以使用.使用static的变量是类变量,也成为静态域(static field).这些是static的基本语义,了解了这些,继续向下看. java核心技术(卷一)对于静态有这样一段