线程

 

线程的创建有三种方式:

1.extends Thread,重写run()方法,在用start()启动。

2.implements Runnableable接口,同样重写run()方法。但区别在于runnable是可运行但不是一个线程,所以仍需要new Thread(实现接口的对象),作为参数传入。

代码如下:

private Runnable target;
 
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
 
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

 

3.匿名类Thread t=new Thread(){重写run和上面相同},好处在于可以访问外部的局部变量。//new Thread(){run..}.start()直接启动

//

//

线程的主要方法:

1.sleep,作用范围和break的作用有点类似。

2.join,可以认为是插队,运行完这个join的再继续上级线程。

3.优先级:

继承:一个线程中创建并运行了另一个线程,两者优先级一致,并且生命周期相互独立

规则:高优先级拥有的资源多

随机性:多资源并不保证一定先完成

//优先级并不是反映在时间上而是在资源的配置上,可以通过实验验证这点

4,守护线程,构造函数中设置True或setter:setDaemon(true);//日志相关功能,生命周期与父线程不独立//进程分为守护进程和用户进程

//

//

 线程同步:在方法前加上synchronized修饰符,将this作为同步对象。所有方法前均有其修饰,则为线程安全的类,同一时间仅有一个线程能修改这个实例的数据。

//

线程安全带来的集合方法差异:

HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式
区别1: 
HashMap可以存放 null
Hashtable不能存放null
区别2:
HashMap不是线程安全的类
Hashtable是线程安全的类

//

StringBuffer 是线程安全的
StringBuilder 是非线程安全的

所以当进行大量字符串拼接操作的时候,如果是单线程就用StringBuilder会更快些,如果是多线程,就需要用StringBuffer 保证数据的安全性

//

Vector是线程安全的类,而ArrayList是非线程安全的。

利用工具类collection中的方法可转换为线程安全的

//List<Integer> list2 = Collections.synchronizedList(list1);

//多线程之间会发生死锁

//

//

线程的交互方法:

//方法实际上是同步对象的方法,不是线程方法,因而前提为线程同步

wait(): 让占用了这个同步对象的线程,临时释放当前的占用,并且等待。 所以调用wait是有前提条件的,一定是在synchronized块里,否则就会出错。

notify(),通知一个等待在这个同步对象上的线程,你可以苏醒过来了,有机会重新占用当前对象了。

notifyAll(),通知所有的等待在这个同步对象上的线程,你们可以苏醒过来了,有机会重新占用当前对象了。

例:

public synchronized void hurt() {
...
this.wait();
...
}

 

posted @ 2020-02-22 22:55  embnaem  阅读(118)  评论(0)    收藏  举报