四个线程t1,t2,t3,t4,向4个文件中写入数据,t1只能写入1,t2只能写入2,t3只能写入3,t4只能写入4,对4个文件A,B,C,D写入如下内容:
A:123412341234…..
B:234123412341….
C:341234123412….
D:412341234123….
怎么实现同步可以让线程并行工作?
CSDN上一个多线程题目,我的解决方案如下:
package micro.test.thread;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.aspectj.weaver.patterns.IfPointcut;
/**
*
* 四个线程t1,t2,t3,t4,向4个文件中写入数据,t1只能写入1,t2只能写入2,t3只能写入3,t4只能写入4,对4个文件A,B,C,
* D写入如下内容: A:123412341234..... B:234123412341.... C:341234123412....
* D:412341234123....
*
*/
public class ThreadTest {
public static void main(String[] args) {
final Files files = new Files();
// ---- 启动4个线程分别打印四个字符 ----
new Thread(new Runnable() {
@Override
public void run() {
synchronized (files) {
while (true) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
files.notifyAll(); // 唤醒其他线程
System.out.println("Thread---" + Thread.currentThread().getName() + " 加锁文件 ");
files.processFile('1');
try {
files.wait(); // 释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "t1").start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (files) {
while (true) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
files.notifyAll(); // 唤醒其他线程
System.out.println("Thread---" + Thread.currentThread().getName() + " 加锁文件 ");
files.processFile('2');
try {
files.wait(); // 释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "t2").start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (files) {
while (true) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
files.notifyAll(); // 唤醒其他线程
System.out.println("Thread---" + Thread.currentThread().getName() + " 加锁文件 ");
files.processFile('3');
try {
files.wait(); // 释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "t3").start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (files) {
while (true) {
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
files.notifyAll(); // 唤醒其他线程
System.out.println("Thread---" + Thread.currentThread().getName() + " 加锁文件 ");
files.processFile('4');
try {
files.wait(); // 释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "t4").start();
// 主线程观察文件实时变化
StringBuffer a = files.getA();
StringBuffer b = files.getB();
StringBuffer c = files.getC();
StringBuffer d = files.getD();
while (true) {
try {
// 主线程休眠
Thread.currentThread().sleep(2000);
System.out.println("-----主线程观察文件变化----");
System.out.println("文件A:" + a);
System.out.println("文件B:" + b);
System.out.println("文件C:" + c);
System.out.println("文件D:" + d);
System.out.println("-----------");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Files {
// 模拟四个文件
private volatile StringBuffer a;
private volatile StringBuffer b;
private volatile StringBuffer c;
private volatile StringBuffer d;
Files() {
// 四个文件初始化
this.a = new StringBuffer();
this.b = new StringBuffer();
this.c = new StringBuffer();
this.d = new StringBuffer();
}
public StringBuffer getA() {
return a;
}
public StringBuffer getB() {
return b;
}
public StringBuffer getC() {
return c;
}
public StringBuffer getD() {
return d;
}
/**
*
* @param c
* @description 这里主要处理每个字符打印线程是否对该文件进行写入
*/
public void processFile(char c) {
System.out.println(Thread.currentThread().getName() + " 处理 " + c);
if (c == '1') {
// 如果文件A为空,或则不为空的情况下前一个字符为4,写入文件
if (a.length() == 0 || (a.length() > 0 && a.charAt(a.length() - 1) == '4')) {
a.append(c);
}
// BCD文件都是不为空并且前一个字符为4,写入文件
if (b.length() > 0 && b.charAt(b.length() - 1) == '4') {
b.append(c);
}
if (this.c.length() > 0 && this.c.charAt(this.c.length() - 1) == '4') {
this.c.append(c);
}
if (d.length() > 0 && d.charAt(d.length() - 1) == '4') {
d.append(c);
}
} else if (c == '2') {
// 同上
if (b.length() == 0 || (b.length() > 0 && b.charAt(b.length() - 1) == '1')) {
b.append(c);
}
if (a.length() > 0 && a.charAt(a.length() - 1) == '1') {
a.append(c);
}
if (this.c.length() > 0 && this.c.charAt(this.c.length() - 1) == '1') {
this.c.append(c);
}
if (d.length() > 0 && d.charAt(d.length() - 1) == '1') {
d.append(c);
}
} else if (c == '3') {
if (this.c.length() == 0 || (this.c.length() > 0 && this.c.charAt(this.c.length() - 1) == '2')) {
this.c.append(c);
}
if (a.length() > 0 && a.charAt(a.length() - 1) == '2') {
a.append(c);
}
if (b.length() > 0 && b.charAt(b.length() - 1) == '2') {
b.append(c);
}
if (d.length() > 0 && d.charAt(d.length() - 1) == '2') {
d.append(c);
}
} else if (c == '4') {
if (d.length() == 0 || (d.length() > 0 && d.charAt(d.length() - 1) == '3')) {
d.append(c);
}
if (a.length() > 0 && a.charAt(a.length() - 1) == '3') {
a.append(c);
}
if (this.c.length() > 0 && this.c.charAt(this.c.length() - 1) == '3') {
this.c.append(c);
}
if (b.length() > 0 && b.charAt(b.length() - 1) == '3') {
b.append(c);
}
}
}
}
结果:
Thread---t1 加锁文件
t1 处理 1
Thread---t4 加锁文件
t4 处理 4
Thread---t3 加锁文件
t3 处理 3
-----主线程观察文件变化----
文件A:1
文件B:
文件C:3
文件D:4
-----------
Thread---t2 加锁文件
t2 处理 2
Thread---t3 加锁文件
t3 处理 3
Thread---t4 加锁文件
t4 处理 4
Thread---t1 加锁文件
t1 处理 1
-----主线程观察文件变化----
文件A:12341
文件B:2341
文件C:341
文件D:41
-----------
Thread---t4 加锁文件
t4 处理 4
Thread---t3 加锁文件
t3 处理 3
Thread---t2 加锁文件
t2 处理 2
Thread---t3 加锁文件
t3 处理 3
-----主线程观察文件变化----
文件A:1234123
文件B:234123
文件C:34123
文件D:4123
-----------
Thread---t4 加锁文件
t4 处理 4
Thread---t1 加锁文件
t1 处理 1
Thread---t4 加锁文件
t4 处理 4
Thread---t3 加锁文件
t3 处理 3
-----主线程观察文件变化----
文件A:123412341
文件B:23412341
文件C:3412341
文件D:412341
-----------
Thread---t2 加锁文件
t2 处理 2
Thread---t3 加锁文件
t3 处理 3
Thread---t4 加锁文件
t4 处理 4
Thread---t1 加锁文件
t1 处理 1
-----主线程观察文件变化----
文件A:1234123412341
文件B:234123412341
文件C:34123412341
文件D:4123412341
-----------
Thread---t4 加锁文件
t4 处理 4
Thread---t3 加锁文件
t3 处理 3
Thread---t2 加锁文件
t2 处理 2
Thread---t3 加锁文件
t3 处理 3
-----主线程观察文件变化----
文件A:123412341234123
文件B:23412341234123
文件C:3412341234123
文件D:412341234123
-----------
Thread---t4 加锁文件
t4 处理 4
Thread---t1 加锁文件
t1 处理 1
Thread---t4 加锁文件
t4 处理 4
Thread---t3 加锁文件
t3 处理 3
-----主线程观察文件变化----
文件A:12341234123412341
文件B:2341234123412341
文件C:341234123412341
文件D:41234123412341
-----------
Thread---t2 加锁文件
t2 处理 2
Thread---t3 加锁文件
t3 处理 3
...