线程基本原理

1、每个线程都会创建自己的栈空间,运行自己的run方法。

线程的两种创建方法:
①如果是重写Thread的run方法,因为使用的自己独有的资源空间,不存在线程同步的问题(没有实现资源共享)。
②如果是多个Thread使用同一个Runnable对象,因为Runnable是一个共享的资源。多个线程要进行访问共享的数据的时候就需要线程同步的技术,否则就会出现数据不同步,也就是线程不安全(可以实现共享资源)。

2、线程同步
线程安全问题都是由全局变量及静态变量引起的。若每个线程对全局变量、静态变量只有读操作,而无写操作,那么这个全局变量是线程安全的。若多个线程同时执行写操作,一般需要考虑线程同步,否则影响线程安全。

数据同步的三个方法:
①同步代码块
格式:锁的对象可以是任意类型,多个线程对象要使用同一把锁。

Object lock=new Object();
synchronized(lock){
    ........
}

②同步方法
格式:

public synchronized void method{
    ....
}

③锁机制(Lock锁,比同步方法和同步代码块功能更强大)
格式:

Lock lock = new ReentrantLock();
lock.lock();
...
lock.unlock();

例子:

public static void main(String[] args) {

        MyRunnable myRunnable = new MyRunnable();
        new Thread(myRunnable).start();
        new Thread(myRunnable).start();
        new Thread(myRunnable).start();

    }


private static class MyRunnable implements Runnable {

    private int ticket = 100;
    Object lockObj = new Object();

   Lock lock = new ReentrantLock();

    @Override
    public void run() {

        /**
        //窗口一直开着,但是对于票操作要进行线程安全控制
        while (true) {
            synchronized (lockObj) {  // ①同步代码块,可以指定任意类型的锁对象
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    String name = Thread.currentThread().getName();
                    System.out.println("==="+name+"   "+(ticket--));
                }


            }
        }
    */

//            sellTicket();



        while (true) {
            lock.lock();  // ③Lock锁
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    String name = Thread.currentThread().getName();
                    System.out.println("==="+name+"   "+(ticket--));
                }
                lock.unlock();
            }
        }


    private synchronized void sellTicket(){//当前的锁对象就是this
        //窗口一直开着,但是对于票操作要进行线程安全控制
        while (true) {
            if (ticket > 0) {
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                String name = Thread.currentThread().getName();
                System.out.println("==="+name+"   "+(ticket--));
            }


        }
    }

}

3、sleep和wait
①Thread.sleep(100);//不会释放锁资源,直到waittingtime到达后继续执行线程体。

②Object.wait()方法,主要用于线程协作的情况,他会释放锁资源。

注意:wait()和notify()必须由同一个锁对象调用,对应的锁对象可以通过notify唤醒使用同一个锁对象调用的wait()方法后的线程。wait()和notify()必须在同步代码块或者同步函数中使用。因为必须通过锁对象调用者2个方法。

当多个线程协作时,比如A、B线程,如果A线程在Runnable(可运行)状态中调用了wait()方法,那么A线程就进入了waiting(无限等待)状态,同时失去了同步锁。假如这个时候B线程获取到了同步锁,在运行状态中调用了notify()方法,那么就会将无限等待的A线程唤醒,如果A获得锁对象,那么A线程就会进入Runnable状态,如果没有获得锁对象,那么就进入到Blocked(锁阻塞状态)。
在这里插入图片描述

例如:

private static Object obj = new Object();

    private static Thread thread1 = new Thread() {

        @Override
        public void run() {
            super.run();
            while (true) {
                synchronized (obj) {  // ①同步代码块,可以指定任意类型的锁对象
                    try {
                        obj.wait();//需要notify notifyAll进行唤醒
//                        obj.wait(50); //自动唤醒
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    String name = Thread.currentThread().getName();
                    System.out.println("===" + name);
                }
            }

        }
    };

    private static Thread thread2 = new Thread() {

        @Override
        public void run() {
            super.run();
            while (true) {
                synchronized (obj) {
                    String name = Thread.currentThread().getName();
                    try {
                        System.out.println("===" + name + "   获取到锁对象,notify thread1");
                        obj.notify();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    };

版权声明:本文为yuezheyue123原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。