线程

2020-05-23  本文已影响0人  wustzhy

线程初始化后的状态:可运行/就绪状态、(抢占到CPU)运行状态、(等待)阻塞状态、(运行完毕)死亡状态

实现

实现线程 方式一 (继承)

run()方法称为 线程体

public class FirstThread extends Thread {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        
        for (int i = 0; i < 100; i++) {
            System.out.println("first thread" + i);
        }
    }
}

使用

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        FirstThread fThread = new FirstThread();
        fThread.start();
        
        for (int i = 0; i < 100; i++) {
            System.out.println("main thread ------ " + i);
        }
    }

运行结果

main thread ------ 0
first thread0
main thread ------ 1
first thread1
main thread ------ 2
first thread2
main thread ------ 3
main thread ------ 4
...

自定义线程 之外,还有主线程、垃圾回收线程。
其中 自定义线程、主线程抢占CPU,交替运行

实现线程 方式二 (实现接口)

public class RunnableImpl implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("impl do sth");
    }
}

RunnableImpl ri = new RunnableImpl();
Thread thread = new Thread(ri);
thread.start();

线程控制

sleep:中断当前线程 [阻塞/休眠状态]

Thread.sleep(2000);//2000ms

那什么时候运行呢?
2000ms后[就绪] + 抢占CPU耗时n后 ->[运行状态]

yield,暂停当前正在执行的线程对象,并让步给其它线程(有机会)执行

 Thread.yield();

什么时候运行?
瞬间中断 -> 抢占资源 -> 运行
有这样的结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果(因为让步的线程还有可能被线程调度程序再次选中)。

thread.setPriority(Thread.MAX_PRIORITY);
thread.setPriority(Thread.MIN_PRIORITY);

默认是5,max:10, min:1
尽管设置了优先级,也并不一定总是优先级高的抢占到CPU,只是概率相对更高一些

多线程数据安全

定义MyThread类,线程体

public class MyThread implements Runnable{
    @Override
    public void run() {
        // TODO Auto-generated method stub
        
        while (true) {
            System.out.println(Thread.currentThread().getName() + i);
            i--;
            Thread.yield();
            if (i < 0) {
                break;
            }
        }
    }
}

多个线程、同一个线程体,运行

static void multiThread() {
    MyThread m = new MyThread();
    Thread t1 = new Thread(m);
    Thread t2 = new Thread(m);
    t1.setName("线程A");
    t2.setName("thread B");
    t1.start();
    t2.start();
}

运行结果

/*  ...
 *  thread B96
    thread B95
    线程A95
    thread B94
    线程A93
    ...
 * */

多线程共用同一份资源(数据)时,操作数据时发生 B95->A95 这样的现象。相当于12306卖票时,同一份票被卖给了2个用户。

使用synchronized,可对共享数据加锁保护

while (true) {
            
    //自动释放锁synchronized,用于多线程中对共享数据保护
    synchronized (this) {
        System.out.println(Thread.currentThread().getName() + i);
        i--;
        Thread.yield();
        if (i < 0) {
            break;
        }
    }
}

不再发生B95->A95这样数据不安全的现象

若A线程拿到这个锁后,执行锁住的代码块。若A还没执行完,此时若B抢占到CPU,B因为没拿到该锁,所以无法使用锁内代码,直到A释放锁,B才有机会拿到锁,才可以在抢占到CPU后执行锁内代码.

上一篇 下一篇

猜你喜欢

热点阅读