今天去公司笔试
有1关于线程的试题
要求:
    启动4个线程,2个线程每次对i加1
                 另外2个每次对i减1               这个需要用到线程同步吗?笔试的时候没写上来。所以现在想总结复习一下。
请教啦!!

解决方案 »

  1.   

    final AtomicInteger i = new AtomicInteger(0);
    new Thread(){
        public void run(){
    while(true)
        System.out.println(i.incrementAndGet());
        }
    }.start();
    new Thread(){
        public void run(){
    while(true)
        System.out.println(i.incrementAndGet());
        }
    }.start();
    new Thread(){
        public void run(){
    while(true)
        System.out.println(i.decrementAndGet());
        }
    }.start();
    new Thread(){
        public void run(){
    while(true)
        System.out.println(i.decrementAndGet());
        }
    }.start();
      

  2.   

    public static void main(String[] args){
    final java.util.concurrent.atomic.AtomicInteger i 
    = new java.util.concurrent.atomic.AtomicInteger(100);
    for (int j = 0;j < 4; j++){
    final int delta = (j%2 == 0)?1:-1;
     new Thread(){
            public void run(){
             while(true)
             System.out.println(i.addAndGet(delta));
            }
        }.start();
    }
    }
      

  3.   


    public class TestThread {

    public static void main(String [] args){

    NumI num = new NumI();
    MyThread thread1 = new MyThread(num, "+");
    MyThread thread2 = new MyThread(num, "+");
    MyThread thread3 = new MyThread(num, "-");
    MyThread thread4 = new MyThread(num, "-");

    thread1.start();
    thread2.start();
    thread3.start();
    thread4.start();

    }
    }
    class MyThread extends Thread {

    private NumI num;
    private String s;

    public MyThread (NumI num, String s){
    this.num = num;
    this.s = s;
    }

    public void run (){
    while(true){

    try{
    Thread.sleep((int)(Math.random()*1000+1000));
    mm();
    }catch(InterruptedException e){
    }

    }
    }

    public synchronized void mm(){

    int i = num.getI();
     
    if(s.equals("+")){
    num.setI(num.getI() + 1);
    }else{
    num.setI(num.getI() - 1);
    }

    System.out.println("i = "+i+" "+s+" 1; "+num.getI());
    }

    }
    class NumI{
    public int i = 0;
    public synchronized void setI(int i){
    this.i = i;
    }
    public synchronized int getI(){
    return i;
    }
    }
      

  4.   

    import java.util.Random;public class Test {
        public static void main(String[] args) {
            SharedResource rs = new SharedResource(); // 共享资源
            
            // 四个Runnable接口使用同一个共享资源
            Changer c1 = new Changer(rs, Changer.OperationMode.ADD_MODE);
            Changer c2 = new Changer(rs, Changer.OperationMode.ADD_MODE);
            Changer c3 = new Changer(rs, Changer.OperationMode.SUB_MODE);
            Changer c4 = new Changer(rs, Changer.OperationMode.SUB_MODE);
            
            // 启动四个线程去操作共享资源
            new Thread(c1).start();
            new Thread(c2).start();
            new Thread(c3).start();
            new Thread(c4).start();
        }
    }class Changer implements Runnable {
        private static int total = 0; // 记录有多少个对象生成了,用来赋值给ID
        private int id; // 对象的唯一ID
        private SharedResource resource;
        private OperationMode mode = OperationMode.ADD_MODE; // 运算模式
        
        public static enum OperationMode {
            ADD_MODE, SUB_MODE
        }
        
        public Changer(SharedResource resource, OperationMode mode) {
            this.resource = resource;
            this.mode = mode;
            this.id = ++total;
        }
        
        @Override
        public void run() {
            // 用随机数来产生线程的随机休眠时间
            Random rand = new Random(System.currentTimeMillis());
            
            // 输出一些运行过程中的信息,好查看运行的结果与过程。
            try {
                for (int i = 0; i < 10; ++i) {
                    switch (mode) {
                    case ADD_MODE:
                        System.out.println("ID: " + id + " Add: " + resource.add());
                        break;
                    case SUB_MODE:    
                        System.out.println("ID: " + id + " Sub: ----> " + resource.sub());
                        break;
                    default:
                    }
                    
                    Thread.sleep(rand.nextInt(300));
                }
            } catch (Exception e) {
            
            }
        }
    }class SharedResource {
        private int i = 0;
        
        // 需要同步的话,在add和sub里加上synchronized同步块.
        // 不需要就去掉
        public synchronized int add() {
            ++i;
            return i;
        }
        
        public synchronized int sub() {
            --i;
            return i;
        }
    }
      

  5.   

    java官方建议使用同步,因为你无法预料每个操作系统平台是怎样定义原子操作的,
    使用i++,i--,是可以不使用同步的,大部分操作系统这两个表达试都是原子操作,也就是说他们能够在一个cpu指令周期把它完成,是不可分割,这样保证所有线程串行操作。