synchronized 的应用 — 交替打印
请编写代码,实现三个线程同时运行,并且能够交替打印。
本题的 Solution 类继承了 Runnable 类并重写 run() 方法,其中有四个成员变量 name 表示线程名、prev 表示前置线程、self 表示当前线程、printCount 表示打印的次数。
在 Main 中已经通过构造 Solution 建立了三个线程 A、B、C,三个线程分别输出字母 A、B 和 C,请你在 run() 方法中编写代码,实现三个线程同时运行,并且能够交替打印各线程对应的字母名称 name,打印的次数 printCount 由 Main 输入获取,即若打印次数 printCount=3,那么就要按照 ABCABCABC 的顺序打印。
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.PrintStream;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
String inputPath = args[0];
String outputPath = args[1];
Scanner sc = new Scanner(new FileReader(inputPath));
PrintStream ps = new PrintStream(outputPath);
// 获取输入的 printCount
Integer printCount = sc.nextInt();
Object oa = new Object();
Object ob = new Object();
Object oc = new Object();
// 建立三个线程
Solution solutionA = new Solution("A", oc, oa, printCount);
Solution solutionB = new Solution("B", oa, ob, printCount);
Solution solutionC = new Solution("C", ob, oc, printCount);
try {
new Thread(solutionA).start();
new Thread(solutionB).start();
new Thread(solutionC).start();
} catch (Exception e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
public class Solution implements Runnable {
private String name;
private Object prev;
private Object self;
private Integer printCount;
private static Object o = new Object();//共享
public Solution(String name, Object prev, Object self, Integer printCount) {
this.name = name;
this.prev = prev;
this.self = self;
this.printCount = printCount;
}
@Override
public void run() {
while (printCount > 0) {
synchronized (prev) {
synchronized (self) {
System.out.print(name);
printCount--;
self.notify();
}
try {
if (printCount == 0) {
prev.notify();
} else {
prev.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
直接实现run方法即可。
@Override
public void run() {
while (printCount > 0) {
synchronized (prev) {
synchronized (self) {
System.out.print(name);
printCount--;
self.notify();
}
try {
if (printCount == 0) {
prev.notify();
} else {
prev.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
55 · 比较字符串
比较两个字符串A和B,确定A中是否包含B中所有的字符。字符串A和B中的字符都是 大写字母
public class Solution {
/**
* @param A : A string includes Upper Case letters
* @param B : A string includes Upper Case letter
* @return : if string A contains all of the characters in B return true else return false
*/
public boolean compareStrings(String A, String B) {
//counts首先记录A中所有的字符以及它们的个数,然后遍历B,如果出现counts[i]小于0的情况,说明B中该字符出现的次数
//大于在A中出现的次数
int[] counts = new int[26];
for (int i = 0; i < 26; i++) {
counts[i] = 0;
}
for (int i = 0; i < A.length(); i++) {
counts[A.charAt(i) - 'A'] ++;
}
for (int i = 0; i < B.length(); i++) {
counts[B.charAt(i) - 'A'] --;
if (counts[B.charAt(i) - 'A'] < 0) {
return false;
}
}
return true;
}
}
6 · 合并排序数组
将按升序排序的整数数组A和B合并,新数组也需有序。
使用两个指针分别对数组从小到大遍历,每次取二者中较小的放在新数组中。
直到某个指针先到结尾,另一个数组中剩余的数字直接放在新数组后面。
class Solution {
/**
* @param A and B: sorted integer array A and B.
* @return: A new sorted integer array
*/
public int[] mergeSortedArray(int[] A, int[] B) {
if (A == null || B == null) {
return null;
}
int[] result = new int[A.length + B.length];
int i = 0, j = 0, index = 0;
while (i < A.length && j < B.length) {
if (A[i] < B[j]) {
result[index++] = A[i++];
} else {
result[index++] = B[j++];
}
}
while (i < A.length) {
result[index++] = A[i++];
}
while (j < B.length) {
result[index++] = B[j++];
}
return result;
}
}