Java并行程序基础
驻守后台:守护进程 进程分为守护进程和用户进程 当用户进程结束后 那么守护进程也相应的结束
package com.longfor.dragonshard.service.cost.standard.impl; public class DaemoDemo extends Thread{ @Override public void run() { while (true){ System.out.println("i am alive"); try{ Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException{ DaemoDemo daemoDemo = new DaemoDemo(); daemoDemo.setDaemon(true); daemoDemo.start(); Thread.sleep(2000); } }
先干重要的事情:线程优先级
线程会有相应的优先级 优先级高的竞争资源会更有优势,更有甚者会抢占资源,当然只是概率问题 如果这样 那么就会产生 '饥饿' 问题,使低优先级无法得到资源
package com.longfor.dragonshard.service.cost.standard.impl; public class PriorityDemo { public static class HighPriority extends Thread{ private static int count = 0; @Override public void run() { while (true){ synchronized (PriorityDemo.class){ if (count>10000){ System.out.println("This is high priority"); break; } count++; } } } } public static class LowPriority extends Thread{ private static int count = 0; @Override public void run() { while (true){ synchronized (PriorityDemo.class){ if (count>10000){ System.out.println("This is low priority"); break; } count++; } } } } public static void main(String[] args) { HighPriority highPriority = new HighPriority(); LowPriority lowPriority = new LowPriority(); highPriority.setPriority(Thread.MAX_PRIORITY); lowPriority.setPriority(Thread.MIN_PRIORITY); highPriority.start(); lowPriority.start(); } }
当使用 volatile 时并不能保证数据的一致性 当多个线程对某一共享数据进行修改时 往往会报错
package com.longfor.dragonshard.service.cost.standard.impl; public class AccountingVol extends Thread{ private static volatile int count = 0; public static void increase(){ count++; } @Override public void run() { for (int i=0;i<100000;i++){ increase(); } } public static void main(String[] args) throws InterruptedException{ AccountingVol accountingVol1 = new AccountingVol(); AccountingVol accountingVol2 = new AccountingVol(); accountingVol1.start(); accountingVol2.start(); accountingVol1.join(); accountingVol2.join(); System.out.println("count: "+count); } }
要想解决这种问题 那么就要使用JAVA提供的 synchronized 关键字,它使得每次只能有一个进程进入同步块 从而保证线程间的安全性
1.指定加锁对象
2.直接作用于实例方法 - 当前实例加锁 同一个实例的加锁方法 普通方法
3.直接作用于静态方法 - 当前类加锁 不同实例的加锁方法 锁类 静态方法
程序中 我们使用 Thread t1 = new Thread(instance); 来使2个线程获得同一实例的锁 从而保证线程间的安全性
package com.longfor.dragonshard.service.cost.standard.impl; public class AccountingSync implements Runnable{ private static AccountingSync instance = new AccountingSync(); private static int count = 0; public static synchronized void increase() { count++; } @Override public void run() { for(int i=0;i<100000;i++){ increase(); } } public static void main(String[] args) throws InterruptedException{ Thread t1 = new Thread(instance); Thread t2 = new Thread(instance); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(count); } }
以下为错误代码 其中不是同一个对象 不同对象的不同普通方法 所以无法可以保证线程的安全性 所以我们只需要在普通方法中加入 static 使得synchronized 锁的是类 从而只能保证安全
加入了synchronized 关键字,相当于使得进程变成了串行方式运行
package com.longfor.dragonshard.service.cost.standard.impl; public class AccountingSync implements Runnable{ private static AccountingSync instance = new AccountingSync(); private static int count = 0; public synchronized void increase() { count++; } @Override public void run() { for(int i=0;i<100000;i++){ increase(); } } public static void main(String[] args) throws InterruptedException{ Thread t1 = new Thread(new AccountingSync()); Thread t2 = new Thread(new AccountingSync()); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(count); } }
逃不过逝水流年 没有时间可以浪费了!!!

浙公网安备 33010602011771号