zoukankan      html  css  js  c++  java
  • Java多线程之简单的线程同步实例

    数据类:

    package Thread.MyCommon;
    
    public class Data {
    
        public int num = 0;
    
        public synchronized int getEven() {
            ++num;
            Thread.yield();//让另外线程先执行,加大测试效果几率
            ++num;
            return num;
        }
    
    }

    线程类:

    package Thread.MyCommon;
    
    public class myThread implements Runnable {
    
        private Data data;
    
        public myThread(Data d) {
            data = d;
        }
    
        @Override
        public void run() {
            while (true)
            {
                int val = data.getEven();
                if (val % 2 != 0) {
                    System.out.println(val + " not even!");
                }
            }
        }
    
    }

    主线程类:

    package Thread.MyCommon;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Main {
        
        
        public static void main(String[] args) {
            Data data=new Data();//多个线程操作的是同一个对象
            ExecutorService executorService=Executors.newCachedThreadPool();
            for (int i = 0; i < 10; i++) {
                executorService.execute(new myThread(data));
            }
            executorService.shutdown();//关闭线程池,如果不关闭线程池将一直运行。
        }
    }

    ------------------------------------------------------------------------------------------

    可以将同步代码改用lock方式:

    package Thread.MyCommon;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Data {
    
        public int num = 0;
    
        Lock lock = new ReentrantLock();
    
        public int getEven() {
            lock.lock();
            try {
                ++num;
                Thread.yield();// 让另外线程先执行,加大测试几率
                ++num;
                return num;// 一定要在unlock之前return,否则数据不同步
            } finally {
                lock.unlock();
            }
            // return num;//不能在unlock之后return,否则数据不同步
        }
    }

    或者改成 synchronized (this)

    package Thread.MyCommon;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Data {
    
        public int num = 0;
    
        Lock lock = new ReentrantLock();
    
        public int getEven() {
            synchronized (this) {
            ++num;
            Thread.yield();// 让另外线程先执行,加大测试几率
            ++num;
            return num;// 一定要在unlock之前return,否则数据不同步
            }
        }
    }

    --------------------------------------------------------------------------

    以下写法,虽然已经同步,但是读取方法不能保证数据是同步的偶数

    package Thread.MyCommon;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class AtomicityTest implements Runnable {
    
        private int i = 0;
    
        public int getValue() {
            return i;
        }
    
        private synchronized void evenIncrement() {
            i++;
            Thread.yield();
            i++;
        }
    
        @Override
        public void run() {
            while (true)
                evenIncrement();
        }
    
        public static void main(String[] args) {
            ExecutorService exec = Executors.newCachedThreadPool();
            AtomicityTest at = new AtomicityTest();
            exec.execute(at);
            while (true) {
                int val = at.getValue();
                if (val % 2 != 0) {
                    System.out.println(val);
                    System.exit(0);
                }
            }
        }
    }
  • 相关阅读:
    玩具数据库
    数据库中可能会出现的表
    SqlDbHelper
    重写 覆盖 虚方法
    页面标签的初始化
    如何将UTF8转换为UTF8n
    小软件项目开发的管理(转)
    SCRUM软件开发过程(转)
    在.Net如何制作自定义的快捷方式
    What Is a Leader
  • 原文地址:https://www.cnblogs.com/zhuawang/p/3753883.html
Copyright © 2011-2022 走看看