实现Thread两种方式

2019-11-06  本文已影响0人  简书_大叔

实现Thread两种方式

1.继承Thread类,简单的代码例子

public class SyncThreadextends Thread {

public SyncThread(String name) {

super(name);

    }

@Override

    public void run() {

super.run();

        // TODO: 执行耗时的逻辑

    }

}

调用代码

new SyncThread("线程一").start();

2.实现Runnable接口

public class SyncRunnable implements Runnable {

@Override

    public void run() {

// TODO: 执行耗时操作逻辑

    }

}

调用代码

new Thread(new SyncRunnable(),"线程二").start();

Thread主要函数

run()//包含线程运行时所执行的代码

start()//用于启动线程

sleep()/sellp(long mills)//线程休眠,交出CPU,让CPU去执行其他的任务,然后线程进入阻塞状态,sleep方法不会释放锁。

yield()//使当前线程交出cpu,让cpu去执行其他的任务,但不会是线程进程进入阻塞状态,而是重置为就绪状态。yield方法不会释放锁。

join()/join(long millis)/join(long mills,int mills,int nanosecongs)//等待线程终止,直白的说,就是发起该子线程的线程 只有等待该线程运行借宿才能继续往下运行

wait()//交出cpu,让CPU执行其他的任务,让线程进人阻塞状态,同时也会释放锁。

interrupt()//中断线程,自stop函数过时之后,我们通过interrup方法和isInterrupdted()方法来停运正在运行的线程,注意只能终端已经处理阻塞的线程。

getId()//获取当前线程ID

getName()/setNamen()//获取和设置线程的名字

getPriority()/setPriodiTY()//获取和这是线程的优先级,一般property用1-10的整数表示,默认优先级是5,优先级最高的是10,优先级高的线程被执行的机率高。

setDaemon/isDaemo()//设置和判断是否守护保护。

currentThread()//静态函数获取当前线程。

Thread线程的主要状态

1.New一旦被实例化之后就处于new状态

2.Runnable调用了start函数之后就处于Running状态

3.Running线程被CPU执行、调用run函数之后就处于Running状态

4.Blocked调用join()、sleep()、wait()使线程处于Blocked状态

5.Dead线程的run()方法运行完毕或者被中断或被异常退出,线程将会到达Dead状态

如何停止一个线程

通过上述函数列表,我们可以知道通过interrupt方法和isInterrupted()方法来停止正在运行的线程,首先必须先让线程处于阻塞状态

/**

    * 销毁线程方法

    */

    private void destroyThread() {

        try {

            if (null != thread && Thread.State.RUNNABLE == thread .getState()) {

                try {

                    Thread.sleep(500);

                    thread .interrupt();

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            thread = null;

        }

    }

Thread线程同步问题

线程的同步是为了防止多个线程访问一个数据对象时,造成数据不一致的问题。

1.举例说明:比如多线程操作一个全局变量

private int count = 100;

    private boolean isRunning = false;

    private void test1() {

        isRunning=true;

        SyncThread syncThread1 = new SyncThread("线程一");

        SyncThread syncThread2 = new SyncThread("线程二");

        SyncThread syncThread3 = new SyncThread("线程三");

        syncThread1.start();

        syncThread2.start();

        syncThread3.start();

    }

    /**

    * 继承Thread方式

    */

    private class SyncThread extends Thread {

        SyncThread(String name) {

            super(name);

        }

        @Override

        public void run() {

            while (isRunning) {

                count();

            }

        }

    }

未加同步的count函数

private void count() {

        if (count > 0) {

            Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);

        } else {

            isRunning = false;

        }

    }

执行结果

添加同步count函数

private void count() {

        synchronized (this) {

            if (count > 0) {

                Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);

            } else {

                isRunning = false;

            }

        }

    }

执行结果

线程同步的几种方式

同样还是以上面的为例

1.同步函数

private void count() {

        synchronized (this) {

            if (count > 0) {

                Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);

            } else {

                isRunning = false;

            }

        }

    }

2.同步代码块

private void count() {

        synchronized (this) {

            if (count > 0) {

                Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);

            } else {

                isRunning = false;

            }

        }

    }

3使用特殊域变量(volatile)实现线程同步

privatevolatileintcount = 1000;

a.volatile关键字为域变量的访问提供了一种免 锁机制。

b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新。

c.因此每次使用该域就要重新计算,而不是使用寄存器中的值。

d.volatile不会提供任何原子操作,他也不能用来修饰final类型的变量。

4.使用重入锁实现线程同步

ReentrantLock();创建一个ReentrantLock实例

lock():获得锁

unlock():释放锁

private void count() {

        lock.lock();

        if (count > 0) {

            Log.e(TAG, Thread.currentThread().getName() + "--->" + count--);

        } else {

            isRunning = false;

        }

        lock.unlock();

    }

上一篇 下一篇

猜你喜欢

热点阅读