大前提:全部线程是没有前后顺序的,若是引入同步锁,谁先得到对象锁,谁先执行ide
线程实现方式:测试
1.继承Thread类,重写run方法;this
2.实现runnable接口,实现其run方法。线程
启动方式:对象
调用线程的start方法启动线程,start方法为线程准备好系统资源,而后调用run方法执行代码逻辑。继承
经常使用方法:接口
Object对象方法:资源
wait和notify方法:这两个方法定义在Object类中,final方法,没法重写,这两方法要求被调用时线程已得到对象的锁,所以须要放在synchronized方法或块中调用。当执行wait方法时,线程会释放对象的锁,线程会处于等待状态;调用notify时,会随机唤醒一个等待的线程(可是不会立马被执行),此唤醒的线程与其余线程竞争对象锁。get
notifyAll方法:也须要在静态方法或静态代码块中执行,会唤醒全部等待的线程跟其余线程进行锁的竞争;同步
当前线程对象的方法:
join:用于将当前线程插入到正在执行的线程,当前线程得到对象锁并执行完后(销毁后)才会继续进行原来正在执行线程未完成的操做。
静态方法:
Thread.sleep方法:会让当前线程休眠指定毫秒时间,整个过程不会释放对象锁。
Thread.yield方法:经当前线程从新置于就绪状态,整个过程不会释放对象锁。
三种使用场景:
1.修饰静态方法:表示对类(Class对象)的枷锁,在进入该静态方法前,当前线程须要得到该类的锁。
一个线程访问该Class对象的任何同步静态方法,其余线程没法访问该Class对象的任何同步方法。
2.修饰普通方法:表示对类实例的加锁,在进入普通方法前,当前线程须要得到该实例的锁(若是是当前类的不一样对象,则不会出现同步显现);
都一个普通方法用synchronized进行修饰,表示对对象加锁,当一个线程调用该方法时,其余线程没法访问该方法,指导第一个线程执行完或抛出异常释放掉对象锁,其余线程才有可能访问该同步方法。
若是一个对象有多个同步方法,当一个线程访问某个同步方法时,其余线程也是没法访问该对象的任何同步方法的。
3.修饰代码块:表示对指定对象枷锁,在进入代码块前,当前线程须要得到该指定对象的锁
同步测试代码以下:
/** * 同步关键字的使用 * 全部线程是没有优先级的(线程执行没有前后顺序),若是引入同步锁,谁先得到对象锁,谁先执行 * * @author kevin * @email ly_triangle@126.com * @date 2018年3月8日 */ public class SynchronizeDemo { /** * 同步静态方法1 */ public synchronized static void synchronizedStaticMethod1() { try { System.out.println(Thread.currentThread().getName() + ":synchronizedStaticMethod1"); Thread.sleep(2000l); System.out.println(Thread.currentThread().getName() + ":synchronizedStaticMethod1……"); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 同步静态方法2 */ public synchronized static void synchronizedStaticMethod2() { System.out.println(Thread.currentThread().getName() + ":synchronizedStaticMethod2"); } /** * 同步普通方法1 */ public synchronized void synchronizedMethod1() { try { System.out.println(Thread.currentThread().getName() + ":synchronizedMethod1"); Thread.sleep(2000l); System.out.println(Thread.currentThread().getName() + ":synchronizedMethod1……"); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 同步普通方法2 */ public synchronized void synchronizedMethod2() { System.out.println(Thread.currentThread().getName() + ":synchronizedMethod2"); } /** * 非同步普通方法1 */ public void method1() { try { System.out.println(Thread.currentThread().getName() + ":synchronizedMethod1"); Thread.sleep(2000l); System.out.println(Thread.currentThread().getName() + ":synchronizedMethod1……"); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 非同步普通方法2 */ public void method2() { System.out.println(Thread.currentThread().getName() + ":synchronizedMethod2"); } /** * 同步代码块1 */ public void synchronizedCodes1() { try { synchronized (this) { System.out.println(Thread.currentThread().getName() + ":synchronizedCodes1"); Thread.sleep(2000l); System.out.println(Thread.currentThread().getName() + ":synchronizedCodes1……"); } } catch (InterruptedException e) { e.printStackTrace(); } } /** * 同步代码块2 */ public void synchronizedCodes2() { System.out.println(Thread.currentThread().getName() + ":synchronizedCodes2 will begining……"); synchronized (this) { System.out.println(Thread.currentThread().getName() + ":synchronizedCodes2"); } } public static void main(String[] args) { /*测试非同步普通方法 * 第二个线程不会等第一个结束就开始执行了 */ SynchronizeDemo demo = new SynchronizeDemo(); new Thread(new Runnable() { @Override public void run() { demo.method1(); } }).start(); new Thread(new Runnable() { @Override public void run() { demo.method2(); } }).start(); /* 测试同步静态方法 *第一个方法执行完毕后才会执行第二个方法 * 除非不是同一个类 */ // new Thread(new Runnable() { // @Override // public void run() { // SynchronizeDemo.synchronizedStaticMethod1(); // } // }).start(); // // new Thread(new Runnable() { // @Override // public void run() { // SynchronizeDemo.synchronizedStaticMethod2(); // } // }).start(); /*测试同步普通方法 * 第一个方法执行完毕才会执行第二个方法 * 除非不是同一个对象 */ // SynchronizeDemo demo = new SynchronizeDemo(); // new Thread(new Runnable() { // @Override // public void run() { // demo.synchronizedMethod1(); // } // }).start(); // // new Thread(new Runnable() { // @Override // public void run() { // demo.synchronizedMethod2(); // } // }).start(); /*测试同步代码块 * 第一个代码块执行完才会执行第二个代码块 * 除非不是同一个对象 */ // SynchronizeDemo demo = new SynchronizeDemo(); // new Thread(new Runnable() { // @Override // public void run() { // demo.synchronizedCodes1(); // } // }).start(); // // new Thread(new Runnable() { // @Override // public void run() { // demo.synchronizedCodes2(); // } // }).start(); } }
wait和notify方法测试:
public class ThreadDemo { public synchronized void run() { try { for (int i = 0; i < 5; i++) { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " ::" + i); if (2 == i) { this.wait(); } } } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void run1() { try { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } this.notify(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { ThreadDemo demo = new ThreadDemo(); new Thread(new Runnable() { @Override public void run() { demo.run(); } }).start(); new Thread(new Runnable() { @Override public void run() { demo.run1(); } }).start(); } } 结果以下: Thread-0 ::0 Thread-0 ::1 Thread-0 ::2 Thread-1 0 Thread-1 1 Thread-1 2 Thread-1 3 Thread-1 4 Thread-0 ::3 Thread-0 ::4
join方法测试:
public class ThreadJoinDemo { public synchronized void runDemo(String threadName, int i) { System.out.println(threadName + ":" + i); } public static void main(String[] args) throws InterruptedException { ThreadJoinDemo demo = new ThreadJoinDemo(); // 定义子线程 Thread thread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 5; i++) { demo.runDemo(Thread.currentThread().getName(), i); } } }); for (int i = 0; i < 5; i++) { demo.runDemo(Thread.currentThread().getName(), i); if (2 == i) { thread.start(); //让主线程释放锁,子线程得到对象锁并执行完后才会接着执行主线程未完的操做 thread.join(); } } } } 结果以下: main 0 main 1 main 2 Thread-0:0 Thread-0:1 Thread-0:2 Thread-0:3 Thread-0:4 main 3 main 4