synchronized
synchronized是一种粗粒度的并发控制,某一时刻,只能有一个线程执行该synchronized方法,synchronized块则是一种细粒度的并发控制,只会将块中的代码同步,位于方法内、synchronized块之外的代码是可以被多个线程同时访问到的。
1.如果某个synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchronized方法所在对象对应类,因为Java中无论一个雷有多少个对象,这些对象会对应唯一一个class对象,因为当线程分别访问同一个类的两个对象的两个static,synchronized方法时,他们的执行顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程才会执行。
public class ThreadTest4 { public static void main(String[] args) { Example example = new Example(); Thread t1 = new TheThread(example); example = new Example(); Thread t2 = new TheThread2(example); t1.start(); t2.start(); } } class Example { public synchronized static void execute() { for(int i = 0; i < 20; i++) { try { Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("hello: " + i); } } public synchronized static void execute2() { for(int i = 0; i < 20; i++) { try { Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("world: " + i); } } } class TheThread extends Thread { private Example example; public TheThread(Example example) { this.example = example; } @Override public void run() { this.example.execute(); } } class TheThread2 extends Thread { private Example example; public TheThread2(Example example) { this.example = example; } @Override public void run() { this.example.execute2(); } }
synchronized块,写法: synchronized (object){} 表示线程在执行过程中,会对object上锁
public class ThreadTest5 { public static void main(String[] args) { Example2 e = new Example2(); TheThread3 t1 = new TheThread3(e); e = new Example2(); TheThread4 t2 = new TheThread4(e); t1.start(); t2.start(); } } class Example2 { private Object object = new Object(); public void execute() { synchronized (this) { for (int i = 0; i < 20; i++) { try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("hello: " + i); } } } public void execute2() { synchronized(this) { for (int i = 0; i < 20; i++) { try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("world: " + i); } } } } class TheThread3 extends Thread { private Example2 example; public TheThread3(Example2 example) { this.example = example; } @Override public void run() { this.example.execute(); } } class TheThread4 extends Thread { private Example2 example; public TheThread4(Example2 example) { this.example = example; } @Override public void run() { this.example.execute2(); } }
死锁(dealock)
wait和notify方法都是定义在Object类中,而且是final的,因此会被所有的java类所继承并且无法重写。这两个方法要求在调用时线程应该已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或者块当中。当线程执行了wait方法时,他会释放掉对象的锁。
另一个会导致线程暂停的方法适Thread类的sleep方法,它会导致线程睡眠指定的毫秒数,但线程在睡眠的过程中是不会释放掉对象的锁的。
珍惜现在,珍惜每一分,每一秒。
从不放弃,坚持。。。。。