Thread

今天写一写关于线程的东西。

线程,现代CPU调度的基本单位,有进程创建,共享进程资源。

java中的线程:Thread

先写一下线程的一个 中断 状态标识。中断标识 用来表示该线程接收到了中断请求。Thread中提供了一些方法来操作中断:

1. 向目标线程发起中断请求,则调用 目标线程 的 interrupt() 方法,该方法是实例方法

2. 查询目标线程的中断状态  isInterrupted() 方法,该方法也是实例方法

3.清除目标线程的中断状态,并返回当前目标线程的中断状态 interrupted方法,该方法是类方法。

interrupt方法 用于设置 中断

isInterrupted方法用于查询中断但不更新(不清除)中断

interrupted方法用于查询中断并更新(清除)中断

线程同步 synchronize,该关键字 可以 解决 多线程 对 同一个 资源的 竞争问题。只有 获取 到锁的 线程,才可以 执行 临界区 的 代码。

那么有一个问题: 如果 当前进入 临界区 的线程, 想释放锁该怎么办? 

如果线程 想释放锁,则可以 调用 锁对象的wait()方法,该方法 会立刻释放锁。

那么还有一个问题: 如果 线程释放锁后被挂起,怎么才能唤醒呢? 则可以调用 锁对象的  notify() 方法 或者 notifyAll()方法 ,就可以唤醒了。notify调用后,会在 执行 完 synchronize 语句块内的代码 才会释放锁

前提是: 必须是 在 synchronize 内部 并且 持有 该锁对象时,才可以 调用。不然会报 

Exception in thread "product" java.lang.IllegalMonitorStateException
    at java.lang.Object.notifyAll(Native Method)

比如典型的 生产者消费者模式,就可以用 synchronize 和 wait/notify 来实现。

创建一个线程需要注意什么?

JDK 提供了9种创建线程对象的 构造方法:

public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
}

public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
}

Thread(Runnable target, AccessControlContext acc) {
        init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}

public Thread(ThreadGroup group, Runnable target) {
        init(group, target, "Thread-" + nextThreadNum(), 0);
}

public Thread(String name) {
        init(null, null, name, 0);
}

public Thread(ThreadGroup group, String name) {
        init(group, null, name, 0);
}

public Thread(Runnable target, String name) {
        init(null, target, name, 0);
}

public Thread(ThreadGroup group, Runnable target, String name) {
        init(group, target, name, 0);
}

public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize) {
        init(group, target, name, stackSize);
}

最终调用的是:

private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;

        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            /* Determine if it's an applet or not */

            /* If there is a security manager, ask the security manager
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }

            /* If the security doesn't have a strong opinion of the matter
               use the parent thread group. */
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }

        /* checkAccess regardless of whether or not threadgroup is
           explicitly passed in. */
        g.checkAccess();

        /*
         * Do we have the required permissions?
         */
        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }

        g.addUnstarted();

        this.group = g;
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        this.target = target;
        setPriority(priority);
        if (inheritThreadLocals && parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }

1. 线程名字 name

2. 线程组 group,  继承 父线程的线程组

3. 是否守护线程  daemon , 继承父线程

4.优先级 priority , 继承父线程

5. 类加载器 contextClassLoader, 继承 父线程

6. Runnable 实现类 target

7. 继承父类已有的 ThreadLocalMap inheritableThreadLocals 的数据

8 线程ID

可以看到,很多属性都是继承父类的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值