int getPriority();
void setPriority(int newPriority);
例如:public class TestPriority { public static void main(String args[]) { Thread t1 = new Thread(new T1()); Thread t2 = new Thread(new T2()); t1.setPriority(Thread.NORM_PRIORITY + 3); t1.start(); t2.start(); }}class T1 implements Runnable { public void run() { for (int i = 0; i < 1000; i++) { System.out.println("T1 " + i); } }}class T2 implements Runnable { public void run() { for (int i = 0; i < 1000; i++) { System.out.println("--------T2: " + i); } }}结果:T1和T2并行运行,但是T1的运行几率比较大(比如运行T1到600然后运行几次T2,只有继续运行T1),并不是T1运行完在运行T2,如果不设置优先级,T1和T2间隔基本相同2.线程同步例:一存折和一银行卡账户上有3000元,当存折在柜台上取2000时,系统检测到有3000,银行工作人员在给你钱但没有更新数据时,另一个人在取款机上用银行卡取2000,系统将数据更新成1000,银行工作人员,办完业务也将数据更新成1000,这样就出现了错误。银行卡和存折就相当于两个线程,解决上述问题,就是在一个线程访问数据时,不允许其他线程访问。访问同一份资源的多个线程之间来进行协调,叫做线程同步。线程同步在java语言中,引入了对象互斥锁的概念,保证共享数据操作的完整性。每个对象都对应于一个可称为互斥锁的标记,这个标记保证在任何时刻,只能又一个线程访问该对象。关键字synchronized来与对象的互斥锁联系,当某个对象synchronized修饰时,表明该对象在任一时刻只能由一线程访问,使用方法如下:public class TestSync implements Runnable { Timer timer = new Timer(); public static void main(String args[]) { TestSync test = new TestSync();//test指向new出来的testSync,testSync //中有timer对象,timer有add方法,t1,t2两个线程都访问了add方法 Thread t1 = new Thread(test); Thread t2 = new Thread(test); t1.setName("t1"); t2.setName("t2"); t1.start(); t2.start(); } public void run() { timer.add(Thread.currentThread().getName()); }}class Timer { private static int num = 0; public void add(String name) { synchronized (this) {//锁定当前对象 num++; try { Thread.sleep(1); } catch (InterruptedException e) { } System.out.println(name + ",你是第" + num + "个使用timer的线程"); } }}结果是:
t1,你是第1个使用timer的线程
t2,你是第2个使用timer的线程
如果去掉synchronized (this)的话,结果会是t1,你是第2个使用timer的线程 t2,你是第2个使用timer的线程,因为在t1访问num++之后进入睡眠,这时num=1,然后t2就能访问num++,此时num=2,t1和t2继续运行就会产生2个2,所以为了避免这中情况发生加入synchronized(this)即是将当前对象锁定,在t1访问时,t2不能访问timer类也可写成:class Timer { private static int num = 0; public synchronized void add(String name) { //synchronized (this) {//锁定当前对象 num++; try { Thread.sleep(1); } catch (InterruptedException e) { } System.out.println(name + ",你是第" + num + "个使用timer的线程"); }}另一个例子:public class TT implements Runnable { int b = 100; public synchronized void m1() throws Exception { b = 1000; Thread.sleep(5000); System.out.println("b = " + b); } public void m2(){ System.out.println(b); } public void run() { try { m1(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { TT tt = new TT(); Thread t = new Thread(tt); t.start(); Thread.sleep(1000); tt.m2(); }}结果是:1000 b=1000虽然tt对象是锁定的,但是锁定的意义是只是锁定的m1方法(其他对象不能在访问m1方法),m2方法仍然可以运行,否则就会输出100。将m2方法改成:public void m2() throws Exception {Thread.sleep(2500);b = 2000;}并去掉main中的Thread.sleep(1000),并在tt.m2后加System.out.println(tt.b)
结果是:2000 b=2000,m1在睡眠锁定时,m2仍然改掉了b的值,要想解决这个问题,必须要给m2也加上锁,b就等于1000,但实际上b的值是2000所以同步的程序,再一个锁定的对象里的值,需要考虑在其他非同步的程序中是否涉及,如果涉及就需要考虑这个方法是否也要锁定。
在给m2也加同步,并在tt.m2后加System.out,println(tt.b),结果是1000,b=1000,main方法运行中加入了m1将b改为1000,并且m1进入睡眠,此时运行m2,m2也进入睡眠,然后就会打印1000,然后m2唤醒,但是m1,m2都是同步状态,并不能影响到m1的输出,所以输出b=1000.3.死锁所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。学过操作系统的朋友都知道:产生死锁的条件有四个:1.互斥条件:所谓互斥就是进程在某一时间内独占资源。2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。例如:死锁是因为多线程访问共享资源,由于访问的顺序不当所造成的,通常是一个线程锁定了一个资源A,而又想去锁定资源B;在另一个线程中,锁定了资源B,而又想去锁定资源A以完成自身的操作,两个线程都想得到对方的资源,而不愿释放自己的资源,造成两个线程都在等待,而无法执行的情况。分析死锁产生的原因不难看出是由访问共享资源顺序不当所造成的,下面写一个造成线程死锁的例子,希望能对大家理解多线程死锁问题有进一步的理解!如果有人需要编写多线程的系统,当操作共享资源时一定要特别的小心,以防出现死锁的情况!public class TestDeadlock implements Runnable { public int flag = 1; static Object o1 = new Object(), o2 = new Object(); public void run() { System.out.println("flag=" + flag); if (flag == 1) { synchronized (o1) { try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } synchronized (o2) { System.out.println("1"); } } } if (flag == 0) { synchronized (o2) { try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } synchronized (o1) { System.out.println("0"); } } } } public static void main(String[] args) { TestDeadlock td1 = new TestDeadlock(); TestDeadlock td2 = new TestDeadlock(); td1.flag = 1; td2.flag = 0; Thread t1 = new Thread(td1); Thread t2 = new Thread(td2); t1.start(); t2.start(); }}结果是:flag=0 flag=1然后无限运行,没有出现终止4.生产者消费者问题public class ProducerConsumer { public static void main(String args[]) { SyncStack ss = new SyncStack(); Producer p = new Producer(ss); Consumer c = new Consumer(ss); new Thread(p).start(); new Thread(c).start(); }}class WoTou { //定义一个生产出来的对象 int id; WoTou(int id) { this.id = id; } public String toString() {//对象返回值 return "WuTou :" + id; }}class SyncStack { //容器使用栈的方式,先进后出 int index = 0; WoTou[] arrWT = new WoTou[6]; public synchronized void push(WoTou wt) { while (index == arrWT.length) { try { this.wait(); //生产满后等待 } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); arrWT[index] = wt; index++; } public synchronized WoTou pop() { while (index == 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); index--; return arrWT[index]; }}class Producer implements Runnable { SyncStack ss = null; Producer(SyncStack ss) { this.ss = ss; } public void run() { for (int i = 0; i < 20; i++) { WoTou wt = new WoTou(i); ss.push(wt); System.out.println("生产了:" + wt); try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } }}class Consumer implements Runnable { SyncStack ss = null; Consumer(SyncStack ss) { this.ss = ss; } public void run() { for (int i = 0; i < 20; i++) { WoTou wt = ss.pop(); System.out.println("消费了:" + wt); try { Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } }}结果:生产了:WuTou :0消费了:WuTou :0生产了:WuTou :1消费了:WuTou :1生产了:WuTou :2消费了:WuTou :2生产了:WuTou :3消费了:WuTou :3生产了:WuTou :4生产了:WuTou :5消费了:WuTou :5消费了:WuTou :4生产了:WuTou :6消费了:WuTou :6生产了:WuTou :7生产了:WuTou :8消费了:WuTou :8生产了:WuTou :9消费了:WuTou :9生产了:WuTou :10生产了:WuTou :11生产了:WuTou :12生产了:WuTou :13生产了:WuTou :14生产了:WuTou :15消费了:WuTou :14消费了:WuTou :15生产了:WuTou :16消费了:WuTou :16生产了:WuTou :17消费了:WuTou :17生产了:WuTou :18消费了:WuTou :18消费了:WuTou :13消费了:WuTou :12生产了:WuTou :19消费了:WuTou :19消费了:WuTou :11消费了:WuTou :10消费了:WuTou :7
新闻热点
疑难解答