JAVA多线程(二)
资源竞争 (线程互斥)
1、什么是资源竞争
有这样一种资源,在某一时刻只能被一个线程所使用:比如打印机、某个文件等等,如果多个线程不加控制的同时使用这类资源,必然会导至错误。
下面的例子模拟了一个打印机,多个线程不加控制的同时使用这个打印机:
public class Printer{ public void print(int printer, String content) { System.out.println("Start working for [" +printer+"]"); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println(content); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println("Work complete for [" +printer+"]\n"); } public static void main(String[] args) { Printer p = new Printer(); for (int i=0; i<3; i++) new Thread(new MyThread(p)).start(); }}class MyThread implements Runnable{ private static int counter = 0; private final int id = counter++; private Printer printer; public MyThread(Printer printer) { this.printer = printer; } @Override public void run() { printer.print(id, "Content of " + id); } }Start working for [0]Start working for [1]======================================Start working for [2]Content of 0Content of 1=========================================================Content of 2Work complete for [0]Work complete for [1]===================Work complete for [2]
public class Printer{ public synchronized void print(int printer, String content) { System.out.println("Start working for [" +printer+"]"); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println(content); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println("Work complete for [" +printer+"]\n"); } public static void main(String[] args) { Printer p = new Printer(); for (int i=0; i<3; i++) new Thread(new MyThread(p)).start(); }}class MyThread implements Runnable{ private static int counter = 0; private final int id = counter++; private Printer printer; public MyThread(Printer printer) { this.printer = printer; } @Override public void run() { printer.print(id, "Content of " + id); } }Start working for [0]===================Content of 0===================Work complete for [0]Start working for [2]===================Content of 2===================Work complete for [2]Start working for [1]===================Content of 1===================Work complete for [1]
public class Printer{ public void print(int printer, String content) { synchronized(this) { System.out.println("Start working for [" +printer+"]"); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println(content); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println("Work complete for [" +printer+"]\n"); } } public static void main(String[] args) { Printer p = new Printer(); for (int i=0; i<3; i++) new Thread(new MyThread(p)).start(); }}class MyThread implements Runnable{ private static int counter = 0; private final int id = counter++; private Printer printer; public MyThread(Printer printer) { this.printer = printer; } @Override public void run() { printer.print(id, "Content of " + id); } }public class Printer{ private Lock lock = new ReentrantLock(); public void print(int printer, String content) { lock.lock(); try { System.out.println("Start working for [" +printer+"]"); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println(content); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println("Work complete for [" +printer+"]\n"); } finally { lock.unlock(); } } public static void main(String[] args) { Printer p = new Printer(); for (int i=0; i<3; i++) new Thread(new MyThread(p)).start(); }}class MyThread implements Runnable{ private static int counter = 0; private final int id = counter++; private Printer printer; public MyThread(Printer printer) { this.printer = printer; } @Override public void run() { printer.print(id, "Content of " + id); } }public class Printer{ private Lock lock = new ReentrantLock(); public void print(int printer, String content) { boolean isLocked = lock.tryLock(); if (!isLocked) return; try { System.out.println("Start working for [" +printer+"]"); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println(content); Thread.yield(); System.out.println("==================="); Thread.yield(); System.out.println("Work complete for [" +printer+"]\n"); } finally { if(isLocked) lock.unlock(); } } public static void main(String[] args) { Printer p = new Printer(); for (int i=0; i<3; i++) new Thread(new MyThread(p)).start(); }}class MyThread implements Runnable{ private static int counter = 0; private final int id = counter++; private Printer printer; public MyThread(Printer printer) { this.printer = printer; } @Override public void run() { printer.print(id, "Content of " + id); } }