Java多线程初探
1 package Network_Experience; 2 3 import javax.swing.*; 4 import java.util.concurrent.locks.ReentrantLock; 5 6 //多线程示例代码 7 public class NET { 8 public static void main(String[] args) { 9 //线程示例化 10 //1.继承Thread类,做一个线程子类(自定义的线程类) 11 MyThread mt = new MyThread(); 12 13 //注意: 14 //需要调用start方法使线程启动 15 //start方法会开启一个新的线程,来执行run中的逻辑 16 mt.start(); 17 18 //2.通过Runnable接口 19 Runnable r = new Runnable() { 20 @Override 21 public void run() { 22 for(int i=0;i<10;i++){ 23 System.out.println("线程2中的逻辑:"+i); 24 } 25 } 26 }; 27 /**通过Lambda表达式也行 28 * Runnable r1 = ()->{ 29 * public void run() { 30 * for(int i=0;i<10;i++){ 31 * System.out.println("线程2中的逻辑:"+i); 32 * } 33 * } 34 * }; 35 */ 36 Thread t2 = new Thread(r); 37 t2.start(); 38 System.out.println("主线程中的逻辑执行结束了"); 39 } 40 } 41 class MyThread extends Thread{ 42 /** 43 * 需要重写run方法 44 * 将需要并发执行的任务写到run方法中 45 */ 46 public void run(){ 47 for(int i=0;i<10;i++){ 48 System.out.println("子线程中的逻辑:"+i); 49 } 50 } 51 } 52 53 54 55 56 57 class ThreadMethod{ 58 public static void main(String[] args) { 59 //线程的命名 60 //1.实例化一个线程对象 61 Thread t = new Thread("Custom"); 62 t.setName("Custom");//两种方法都行 63 //与其在Thread的构造参数中单单提供name,Thread(Runnable r,String name)更加常用 64 //2.通过Thread子类的重写构造方法进行命名 65 MyThread2 mt2 = new MyThread2("Custom"); 66 67 //System.out.println(t.getName()); 68 //System.out.println(mt2.getName()); 69 70 //threadSleep(); 71 //threadPriority(); 72 //threadYield(); 73 74 } 75 private static void threadSleep(){ 76 MyThread2 t2 = new MyThread2(); 77 t2.start(); 78 } 79 private static void threadPriority(){ 80 //设置线程的优先级,只是修改此线程可以抢到CPU时间片的概率 81 //并不是优先级高的线程一定能抢到CPU时间片 82 //优先级的设置,是一个[0,10]的整数,默认为5 83 Runnable r =()->{ 84 for(int i=0;i<100;i++){ 85 System.out.println(Thread.currentThread().getName()+":"+i); 86 } 87 }; 88 Thread t1 = new Thread(r,"T1"); 89 Thread t2 = new Thread(r,"T2"); 90 91 //设置优先级(必须要放置在start之前) 92 t1.setPriority(10); 93 t2.setPriority(1); 94 95 t1.start(); 96 t2.start(); 97 98 } 99 private static void threadYield(){ 100 //线程的礼让:让当前的运行态的线程释放自己的CPU资源,从运行态返回就绪态 101 Runnable r = new Runnable() { 102 @Override 103 public void run() { 104 for(int i=0;i<10;i++){ 105 System.out.println(Thread.currentThread().getName()+" : "+i); 106 if(i==5){ 107 Thread.yield(); 108 } 109 110 } 111 } 112 }; 113 Thread y1 = new Thread(r,"Thread-1"); 114 Thread y2 = new Thread(r,"Thread-2"); 115 116 y1.start(); 117 y2.start(); 118 } 119 } 120 class MyThread2 extends Thread{ 121 MyThread2(){}; 122 MyThread2(String name){ 123 super(name); 124 //this.setName(name);也可 125 } 126 public void run(){ 127 for(int i=0;i<10;i++){ 128 System.out.println(i); 129 //线程休眠 130 //1.参数:毫秒为单位的时间差,注意捕获异常 131 try{ 132 Thread.sleep(1000); 133 }catch (InterruptedException e){ 134 e.printStackTrace(); 135 } 136 } 137 } 138 } 139 140 141 142 143 class SourceConflict{//临界资源问题:由于多个线程争抢同一片资源造成的问题 144 public static void main(String[] args) { 145 Runnable r =()->{ 146 /** while(TicketCenter.restCount > 0){ 147 System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+ --TicketCenter.restCount+"张"); 148 //在输出语句的时刻有另外的线程争抢资源,导致输出语句滞后 149 }*/ 150 //解决办法:加上对象锁,即synchronized (""),在一个线程夺得资源后其他线程夺取资源也得等这个线程执行完语句 151 //或者加上类锁,即synchronize(SynchronizedDemo.class)也可 152 //需要保证一点:所有线程看到的锁都是同一把锁才有效 153 while(TicketCenter.restCount>0){ 154 synchronized (""){ 155 if(TicketCenter.restCount<=0){ 156 return; 157 } 158 System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+ --TicketCenter.restCount+"张"); 159 } 160 } 161 }; 162 Thread t1 = new Thread(r,"Thread-1"); 163 Thread t2 = new Thread(r,"Thread-2"); 164 Thread t3 = new Thread(r,"Thread-3"); 165 Thread t4 = new Thread(r,"Thread-4"); 166 167 t1.start(); 168 t2.start(); 169 t3.start(); 170 t4.start(); 171 } 172 } 173 class TicketCenter{ 174 public static int restCount = 100; 175 } 176 177 178 class SynchronizedFunction{//同步方法 179 public static void main(String[] args) { 180 Runnable r =()->{ 181 while(TicketCenter.restCount>0){ 182 soldTicket();//这样与前一个类的实现等效,将同步代码段写在一个方法中 183 } 184 }; 185 Thread t1 = new Thread(r,"Thread-1"); 186 Thread t2 = new Thread(r,"Thread-2"); 187 Thread t3 = new Thread(r,"Thread-3"); 188 Thread t4 = new Thread(r,"Thread-4"); 189 190 t1.start(); 191 t2.start(); 192 t3.start(); 193 t4.start(); 194 } 195 196 /** 197 * 同步的方法 198 * 静态方法:类锁 当前类.class 199 * 非静态方法:同步锁 this 200 */ 201 private synchronized static void soldTicket(){ 202 if(TicketCenter.restCount<=0){ 203 return; 204 } 205 System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+ --TicketCenter.restCount+"张"); 206 } 207 } 208 209 class LockExample{ 210 public static void main(String[] args) { 211 212 //显式锁,实例化一个锁对象,效果和同步化代码一致 213 ReentrantLock lock = new ReentrantLock(); 214 215 Runnable r =()->{ 216 while(TicketCenter.restCount>0){ 217 lock.lock();//上锁 218 if(TicketCenter.restCount<=0){ 219 return; 220 } 221 System.out.println(Thread.currentThread().getName()+"卖出一张票,剩余"+ --TicketCenter.restCount+"张"); 222 lock.unlock();//解锁 223 } 224 }; 225 Thread t1 = new Thread(r,"Thread-1"); 226 Thread t2 = new Thread(r,"Thread-2"); 227 Thread t3 = new Thread(r,"Thread-3"); 228 Thread t4 = new Thread(r,"Thread-4"); 229 230 t1.start(); 231 t2.start(); 232 t3.start(); 233 t4.start(); 234 } 235 } 236 237 class DeadLock{ 238 //死锁示例:多个线程彼此持有对方需要的锁对象,但都不释放自己的锁 239 //解决办法:wait/notify 240 //wait:Object类中的方法,使当前线程释放自己的锁标记并让出CPU资源,当前线程进入等待队列 241 //notify:Object类中的方法,唤醒等待队列中的一个线程并使此线程进入锁池 242 //notifyAll:Object类中的方法,唤醒等待队列中的所有等待这个锁的线程并使它们进入锁池,如"a".notifyAll();释放所有等待"a"的线程 243 public static void main(String[] args) { 244 Runnable r1 = ()->{ 245 synchronized ("A"){ 246 System.out.println("A线程持有A锁并等待B锁"); 247 248 //A线程释放已有的A锁并进入等待队列 249 try { 250 "A".wait();//如果"C".wait();会异常 251 } catch (InterruptedException e) { 252 e.printStackTrace(); 253 } 254 255 synchronized ("B"){ 256 System.out.println("A线程同时持有A和B两把锁"); 257 } 258 } 259 }; 260 Runnable r2 = ()->{ 261 synchronized ("B"){ 262 System.out.println("B线程持有B锁并等待A锁"); 263 synchronized ("A"){ 264 System.out.println("B线程同时持有B和A两把锁"); 265 "A".notify(); 266 } 267 } 268 }; 269 Thread t1 = new Thread(r1); 270 Thread t2 = new Thread(r2); 271 272 t1.start(); 273 t2.start(); 274 } 275 } 276 277 class SingletonTest{//单例在多线程中的问题 278 public static void main(String[] args) { 279 Runnable runnable = ()->{ 280 Boss.getBoss(); 281 }; 282 for(int i=0;i<100;i++){ 283 new Thread(runnable).start(); 284 } 285 } 286 } 287 class Boss{//懒汉式单例:只有当对象被检测到没有实例化时才调用方法进行实例化 288 private Boss(){ 289 System.out.println("一个Boss对象被实例化了"); 290 } 291 private static Boss instance = null; 292 public static Boss getBoss(){ 293 synchronized (""){//通过同步锁可以解决单例在多线程中出现的问题 294 if(instance==null){ 295 instance = new Boss(); 296 }} 297 return instance; 298 } 299 }