例1:单线程
Punishment.java
public class Punishment {
private int leftCopyCount;
private String wordToCopy;
public Punishment(int i, String s) {
this.leftCopyCount = i;
this.wordToCopy = s;
}
public int getLeftCopyCount() {
return leftCopyCount;
}
public void setLeftCopyCount(int leftCopyCount) {
this.leftCopyCount = leftCopyCount;
}
public String getWordToCopy() {
return wordToCopy;
}
public void setWordToCopy(String wordToCopy) {
this.wordToCopy = wordToCopy;
}
}
Student.java
public class Student {
private String name;
private Punishment punishment;
public Student(String name,Punishment punishment){
this.name = name;
this.punishment = punishment;
}
public void copyWord(){
int count = 0;
String threadName = Thread.currentThread().getName();
while(true){
if(punishment.getLeftCopyCount() > 0){
int leftCopyCount = punishment.getLeftCopyCount();
System.out.println(threadName+"线程-" + name + "抄写" + punishment.getWordToCopy() + "。还要抄写" +
--leftCopyCount + "次");
punishment.setLeftCopyCount(leftCopyCount);
count++;
}else{
break;
}
}
System.out.println(threadName + "线程-" + name + "一共抄写了" + count + "次!");
}
}
StudentClient.java
public class StudentClient {
public static void main(String[] args) {
Punishment punishment = new Punishment(100,"internationalization");
Student student = new Student("小明",punishment);
student.copyWord();
}
}
main线程-小明抄写internationalization。还要抄写99次
...
main线程-小明抄写internationalization。还要抄写0次
main线程-小明一共抄写了100次!
例2:继承Thread实现独立线程
与例1不同处:
- 继承Thread类
- 调用Thread构造方法,设置threadName
- 重写run方法,调用copyWord完成任务
- 在main()中调用 start 方法
Student.java
public class Student extends Thread{
private String name;
private Punishment punishment;
public Student(String name,Punishment punishment){
super(name);
this.name = name;
this.punishment = punishment;
}
public void copyWord(){
int count = 0;
String threadName = Thread.currentThread().getName();
while(true){
if(punishment.getLeftCopyCount() > 0){
int leftCopyCount = punishment.getLeftCopyCount();
System.out.println(threadName+"线程-" + name + "抄写" + punishment.getWordToCopy() + "。还要抄写" +
--leftCopyCount + "次");
punishment.setLeftCopyCount(leftCopyCount);
count++;
}else{
break;
}
}
System.out.println(threadName + "线程-" + name + "一共抄写了" + count + "次!");
}
@Override
public void run(){
copyWord();
}
}
StudentClient.java
public class StudentClient {
public static void main(String[] args) {
Punishment punishment = new Punishment(100,"internationalization");
Student student = new Student("小明",punishment);
student.start();
System.out.println("Another thread will finish the punishment。 main thread is finished" );
}
}
Another thread will finish the punishment。 main thread is finished
小明线程-小明抄写internationalization。还要抄写99次
...
小明线程-小明抄写internationalization。还要抄写0次
小明线程-小明一共抄写了100次!
例2:继承Thread实现多线程
StudentClient.java
public class StudentClient {
public static void main(String[] args) {
Punishment punishment = new Punishment(100,"internationalization");
Student xiaoming = new Student("小明",punishment);
xiaoming.start();
Student xiaozhang = new Student("小张",punishment);
xiaozhang.start();
Student xiaozhao = new Student("小赵",punishment);
xiaozhao.start();
}
}
小明线程-小明一共抄写了100次!
小张线程-小张一共抄写了100次!
小赵线程-小赵一共抄写了100次!
例3:继承Runnable实现多线程
Student.java
public class Student implements Runnable{
private String name;
private Punishment punishment;
public Student(String name,Punishment punishment){
this.name = name;
this.punishment = punishment;
}
public void copyWord(){
int count = 0;
String threadName = Thread.currentThread().getName();
while(true){
if(punishment.getLeftCopyCount() > 0){
int leftCopyCount = punishment.getLeftCopyCount();
System.out.println(threadName+"线程-" + name + "抄写" + punishment.getWordToCopy() + "。还要抄写" +
--leftCopyCount + "次");
// --leftCopyCount;
punishment.setLeftCopyCount(leftCopyCount);
count++;
}else{
break;
}
}
System.out.println(threadName + "线程-" + name + "一共抄写了" + count + "次!");
}
@Override
public void run(){
copyWord();
}
}
StudentClient.java
public class StudentClient {
public static void main(String[] args) {
Punishment punishment = new Punishment(100,"internationalization");
Thread xiaoming = new Thread(new Student("小明",punishment));
xiaoming.start();
}
}
结果同例2
例4:多线程同时抄写
- 取得剩余次数后马上更新-1后的次数。看似是避免了读取和更新间的时间间隔
- 更新剩余次数前先判断自己的更新次数是否为最新,避免更新后次数反而变大的问题
- 有小概率两人甚至三人同时查看剩余次数,导致重复抄写
Student.java
public class Student extends Thread{
private String name;
private Punishment punishment;
public Student(String name,Punishment punishment){
super(name);
this.name = name;
this.punishment = punishment;
}
public void copyWord(){
int count = 0;
String threadName = Thread.currentThread().getName();
while(true){
if(punishment.getLeftCopyCount() > 0){
int leftCopyCount = punishment.getLeftCopyCount();
leftCopyCount--;
if(leftCopyCount<punishment.getLeftCopyCount()){
punishment.setLeftCopyCount(leftCopyCount);
}
System.out.println(threadName+"线程-" + name + "抄写" + punishment.getWordToCopy() + "。还要抄写" +
leftCopyCount + "次");
count++;
}else{
break;
}
}
System.out.println(threadName + "线程-" + name + "一共抄写了" + count + "次!");
}
@Override
public void run(){
copyWord();
}
}
StudentClient.java
public class StudentClient {
public static void main(String[] args) {
Punishment punishment = new Punishment(100,"internationalization");
Student xiaoming = new Student("小明",punishment);
xiaoming.start();
Student xiaozhang = new Student("小张",punishment);
xiaozhang.start();
Student xiaozhao = new Student("小赵",punishment);
xiaozhao.start();
}
}
小赵线程-小赵一共抄写了34次!
小张线程-小张一共抄写了22次!
小明线程-小明一共抄写了44次!
例5:解决线程安全问题

参考
java多线程是并发还是并行
https://blog.csdn.net/gxl1989225/article/details/84912017