------- android培训、java培训、期待与您交流! ----------
同步函数:
show();方法本身没有同步性,但我们加上sychronized标记后就具备了同步性。
class Ticket implements Runnable { private int num = 100; //private Object obj = new Object(); 同步函数使用的锁是this 这里我们将boject注释掉,程序也没问题, public void run() { while(true) { show(); } } //同步函数 public synchronized void show() { if(num>0) { try{Thread.sleep(10);}catch(InterruptedException e){} System.out.println(Thread.currentThread().getName()+".....sale....."+num--); } } } class TicketDemo3 { public static void main(String[] args) { Ticket t = new Ticket(); //创建线程对象。 Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); Thread t4 = new Thread(t); t1.start(); t2.start(); t3.start(); t4.start(); } }那么同步函数和同步代码块的区别是:①书写,同步函数书写简单②用的锁不一样,同步函数使用的锁是this;同步代码块使用的锁是任意对象
然而当静态方法在编译的时候还没有this也没有对象,所以静态方法若要同步,使用的锁是该类字节码文件对象----表示方式:类名.class
死锁
最常见的死锁情况,同步的嵌套:同步中还有同步,两个同步用的不是一个锁。
我们应当,尽量避免同步嵌套的情况。
class Clock { //锁使用的2个对象 public static Clock locka = new Clock(); public static Clock lockb = new Clock(); } class DeadLock implements Runnable { private boolean flag; //定义Boolean变量 public DeadLock(boolean flag){ this.flag = flag; } @Override public void run() { if(flag){ //让2个线程进入不同的锁当中 while(true){ synchronized(Clock.locka){ //线程T1在locka的锁准备进入lockb的锁中 System.out.println(".................if locka"); synchronized(Clock.lockb){ System.out.println(".................if lockb"); } } } } else{ while(true){ synchronized(Clock.lockb){ 线程t2在lockb的锁中准备进入locka的锁中 System.out.println("-------------------------else lockb"); synchronized(Clock.locka){ System.out.println("----------------------else locka"); } } } } } } public class DeadLockTest { public static void main(String[] args) { DeadLock d1 = new DeadLock(true); //创建对象,并设定Boolean值 DeadLock d2 = new DeadLock(false); <span style="font-family: Arial;">//创建对象,并设定Boolean值</span> Thread t1 = new Thread(d1); //创建线程,传人对象 Thread t2 = new Thread(d2); t1.start(); //开启线程 t2.start(); } }例中,当先线程当t1 拿到 Clock.locka , 当线程t2 拿到 Clock.lockb时,线程t1 需要 Clock.lockb 来继续运行,线程t2 需要 Clock.locka 来继续运行,而此时锁中都有运行着的线程,对方不能进入,造成了死锁的状况。
java中的等待唤醒机制
class Resource { private String name ; private String sex; private boolean flag = false; public synchronized void set(String name , String sex){ if(flag) try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } this.name = name; //设置成员变量 this.sex = sex; flag = true; //设置之后,Resource中有值,将标记该为 true , this.notify(); //唤醒output } public synchronized void out(){ if(!flag) try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("The name is : " + name + " && The sex is : " + sex); //输出线程将数据输出 flag = false;//改变标记,以便输入线程输入数据 this.notify(); //唤醒input,进行数据输入 } } class Input implements Runnable { private Resource r; public Input(Resource r){ this.r = r; } public void run() { int count = 0 ; while(true){ if(count == 0){ r.set("Tom", "man"); }else{ r.set("Lily", "woman"); } count = (count + 1)%2; //每执行到一次设置一次name和性别。 } } } class Output implements Runnable { private Resource r ; public Output(Resource r ){ this.r = r; } public void run() { while(true){ r.out(); } } } public class ResorseDemo { public static void main(String[] args) { Resource r = new Resource(); //资源对象 Input in = new Input(r); //任务对象 Output out = new Output(r); Thread t1 = new Thread(in); //线程对象 Thread t2 = new Thread(out); t1.start(); //开启线程t1 t2.start(); } }
在这个例子中,我们应用了等待唤醒机制:input() 和output()利用wait()和notify();及设置Boolean值来交替输入和打印一组姓名----年龄。
线程的优先级
当有多个线程同时处于可执行状态(就绪状态)哄抢CPU控制权时
优先级能够使得优先级高的线程有更大的机会获得 CPU 控制权,优先级低的线程机会要小
JAVA 里面定义了10级
可以用setPriority来设置线程的优先级,getPriority取得线程的优先级:
import sharevar.Machine; public class priority extends Thread { private static StringBuffer log=new StringBuffer(); private static int count=0; public void run() { for (int a=0;a<20;a++) { log.append(currentThread().getName()+":"+a); if (++count %10==0) log.append("\n"); } } public static void main(String[] args) { // TODO Auto-generated method stub Machine m1=new Machine(); Machine m2=new Machine(); m1.setName("m1"); m2.setName("m2"); Thread main=Thread.currentThread(); //获得主线程 //查看和设置线程的优先级 System.out.println("default priority of main:"+main.getPriority()); //打印m2线程默认优先级 System.out.println("default priority of m1:"+m1.getPriority()); //打印m2线程默认优先级 System.out.println("default priority of m2:"+m2.getPriority()); m2.setPriority(Thread.MAX_PRIORITY); m1.setPriority(Thread.MIN_PRIORITY); m1.start();//开启线程 m2.start(); System.out.println(log); } }