Java多线程及线程之间的通信的几个想法和小实验
1.通过synchronized,wait,notify实现线程的同步
1.编写Java应用程序实现如下功能:第一个线程生成一个随机数,第二个线程每隔一段时间读取第一个线程生成的随机数,并判断它是否是奇数。要求采用实现Runnable接口和Thread类的构造方法的方式创建线程,而不是通过Thread类的子类的方式。在报告中附上程序截图、完整的运行结果截图和简要文字说明。
package work_11_17_02;
class Num{
private int num;
private boolean condition=false;
public synchronized void write(){
for(int i=0;i<30;i++){
if(!condition){
num=(int)(Math.random()*100);
condition=true;
try{Thread.sleep(100);}
catch(InterruptedException e){}
notify();
}
try{wait();}
catch(InterruptedException e){}
}
}
public synchronized void get(){
for(int i=0;i<30;i++){
if(condition){
if(num%2!=0){
System.out.println(num+"是奇数");
}else{
System.out.println(num+"是偶数");
}
condition=false;
try{Thread.sleep(100);}
catch(InterruptedException e){}
notify();
}
try{wait();}
catch(InterruptedException e){}
}
}
}
class Generate implements Runnable{
private Num account;
public Generate(Num t){
account=t;
}
public void run(){
account.write();
}
}
class Reader implements Runnable{
private Num account;
public Reader(Num t){
account=t;
}
public void run(){
account.get();
}
}
public class Main {
public static void main(String args[]){
Num account=new Num();
Thread t1,t2;
t1=new Thread(new Generate(account));
t2=new Thread(new Reader(account));
t1.start();
t2.start();
}
}
2.编写Java应用程序实现如下功能:第一个线程输出数字1-26,第二个线程输出字母A-Z,输出的顺序为1A2B3C…26Z,即每1个数字紧跟着1个字母的方式。要求线程间实现通信。要求采用实现Runnable接口和Thread类的构造方法的方式创建线程,而不是通过Thread类的子类的方式。
package work_11_17_03;
class Center//这两个线程的关系不是生产者--消费者
{
private boolean condition=false;//先打印数字
public synchronized void printNumber(){
for(int i=1;i<=26;i++){
if(!condition){
System.out.print(i);
condition=true;
try{Thread.sleep(100);}
catch(InterruptedException e){}//睡一觉才叫别人干事
notify();//做完事之后notify另一个线程
}
try{wait();}//然后自己进入等待模式
catch(InterruptedException e){}
}
}
public synchronized void printChar(){
for(int i=1;i<=26;i++){
if(condition){
System.out.print((char)('A'+i-1));
condition=false;
try{Thread.sleep(100);}
catch(InterruptedException e){}
notify();
}
try{wait();}
catch(InterruptedException e){}
}
}
};
class Number implements Runnable
{
private Center center01;
public Number(Center temp){
center01=temp;
}
public void run(){
center01.printNumber();
}
};
class Char implements Runnable
{
private Center center02;
public Char(Center temp){
center02=temp;
}
public void run(){
center02.printChar();
}
};
public class Main01 {
public static void main(String args[]){
Center task=new Center();
Thread t1,t2;
t1=new Thread(new Number(task));
t2=new Thread(new Char(task));
t1.start();
t2.start();
}
}
2. 当出现三个及三个以上的线程时,使用线程池进行管理
编写Java应用程序实现如下功能:创建工作线程,模拟银行现金账户存款操作。多个线程同时执行存款操作时,如果不使用同步处理,会造成账户余额混乱,要求使用syncrhonized关键字同步代码块,以保证多个线程同时执行存款操作时,银行现金账户存款的有效和一致。要求采用实现Runnable接口和Thread类的构造方法的方式创建线程,而不是通过Thread类的子类的方式。
package work_11_17_04;
import java.util.concurrent.*;
class Center
{
private int sum=0;
public synchronized void deposit(String name,int d){
sum+=d;
System.out.println(name+" deposit :"+d+" sum :"+sum);//存钱
notifyAll();//存完之后唤醒其他线程
try{Thread.sleep(100);}//睡上一觉
catch(InterruptedException e){}
try{wait();}//线程进入等待状态
catch(InterruptedException e){}
}
};
class Person implements Runnable{
private Center s;
private int money;
public Person(Center s,int money){
this.s=s;
this.money=money;
}
public void run(){
Thread t=Thread.currentThread();
for(int i=0;i<20;i++){
s.deposit(t.getName(), money);
}
}
}
public class Main {
public static void main(String args[]){
ExecutorService executor=Executors.newFixedThreadPool(3);
Center task=new Center();
executor.execute(new Person(task, 3000));
executor.execute(new Person(task, 20));
executor.execute(new Person(task, 460));
executor.shutdown();
}
}
3.生产者—消费者多线程模型
这里直接根据代码进行演示
package threadLearn;
class Account{//这是一个账户,父亲和儿子共有,父亲存钱,儿子取钱
private double balance;
private String name;
Account(String name,double b){
this.name=name;
balance=b;
}
public synchronized void save(double d){
while(balance>5000){//资金是判断哪个线程该工作哪个线程该休息的key
try{wait();}//当账户的钱多于5000的时候,father就wait,就算son来notify他,由于循环,father继续wait
catch(InterruptedException e){}
}
balance+=d;//当资金少于5000时(由son不断地take),此时son的notify让father跳出了循环,给账户save
try{Thread.sleep(500);}//睡一觉
catch(InterruptedException e){}
System.out.println("Save :"+d+" balance :"+balance);
notify();//notify儿子有钱了,快来取
}
public synchronized void take(double d){//情况与父亲相同
while(balance<5000){
try{wait();}
catch(InterruptedException e){}
}
balance-=d;
try{Thread.sleep(500);}
catch(InterruptedException e){}
System.out.println("take :"+d+" balance :"+balance);
notify();
}
};
class Son implements Runnable{
private Account a;//用同一个account对son和father的account进行初始化
Son(Account a){
this.a=a;
}
public synchronized void run(){
for(int i=0;i<5;i++){
a.take(5000);
}
}
}
class Father implements Runnable{
private Account a;
Father(Account a){
this.a=a;
}
public synchronized void run(){
for(int i=0;i<5;i++){
a.save(5000);
}
}
}
public class t3 {
public static void main(String args[]){
Account a=new Account("tim", 0);
new Thread(new Father(a)).start();
new Thread(new Son(a)).start();
}
}
目的
一个笔记
未完待续…