之前的博文对Java线程通信做了简单的介绍....
接下来对多个线程访问共享对象和数据的方式做一总结:
1. 如果每个线程执行的代码相同 可以使用同一个Runnable对象 这个Runnable对象中有那个共享数据 例如 卖票系统就可以这么做
卖票系统的例子:Code 如下...
//售票任务
class SellTicker implements Runnable{
private int ticket_count = 100;
public void run() {
while(ticket_count>0){
ticket_count--;
System.out.println("name:"+Thread.currentThread().getName()+"......."+"剩余票数:"+ticket_count);
}
}
}
main(){
SellTicker sellTicket = new SellTicker();
new Thread(sellTicket).start();
new Thread(sellTicket).start();
new Thread(sellTicket).start();
}
2.如果每个线程执行的代码不同 这时候需要不同的Runnable对象
2.a : 将共享数据封装在另外一个对象中 然后将这个对象逐一传递给各个Runnable对象 每个线程对共享数据的操作也分配到那个对象身上去完成 这样容易实现针对该数据进行的各个操作的互斥跟通信
2.b : 将这些Runnable对象作为某一个类的内部类 共享数据作为外部类中的成员变量 每个线程对共享数据的操作也分配给外部类 以便实现共享数据进行的各个操作的互斥和通信 作为内部类的各个Runnable对象调用外部类的这些方法
2.c : 上面俩种方式的组合 将共享数据封装到一个对象中 每个线程对共享数据的操作也分配到那个对象上去 对象作为外部类的成员变量 或者方法中的局部变量 每个线程中的Runnable对象作为外部类中的成员内部类或者局部内部类
总之 要同步互斥的几段代码最好是分别放在几个独立的方法中 这些方法再放到同一个类中 这样较容易实现它们之间的互斥和通信
设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
public class ThreadTest1
{
private int j;//共享数据
public static void main(String args[]){
ThreadTest1 tt=new ThreadTest1();
Inc inc=tt.new Inc();
Dec dec=tt.new Dec();
for(int i=0;i<2;i++){
Thread t=new Thread(inc);
t.start();
t=new Thread(dec);
t.start();
}
}
//对数据的操作 加this锁
private synchronized void inc(){
j++;
System.out.println(Thread.currentThread().getName()+"-inc:"+j);
}
//对共享数据的操作 加
this
锁
private synchronized void dec(){
j--;
System.out.println(Thread.currentThread().getName()+"-dec:"+j);
}
//在Runnable对象中执行对共享数据的操作
class Inc implements Runnable{
public void run(){
for(int i=0;i<100;i++){
inc();
}
}
}
//对共享数据的操作在Runnable对象中操作
class Dec implements Runnable{
public void run(){
for(int i=0;i<100;i++){
dec();
}
}
}
}