美文网首页
Java -- 线程

Java -- 线程

作者: _Raye | 来源:发表于2017-01-03 19:53 被阅读0次

    线程

    • 线程的三种状态(五种状态)
      1. 运行态(Running) ---> yield() ---> 就绪态
      2. 就绪态(Runnable)
      3. 阻塞态(Blocked)
        sleep( ) / IO中断 / join( )
        wait( ) ---> 等待池 ---> notify( ) / notifyAll( ) ---> 等待池
        synchronized ---> 等锁池 ---> 抢锁池 ---> 就绪态
    • Thread类有两个静态方法可以让正在执行的线程放弃对cup的占用
      1.sleep - 让CPU的时候不考虑优先级,yield要考虑优先级。
      2.yield - 让出CPU后进入就绪态,sleep让出CPU后进入阻塞态
    public class Frame extends JFrame implements ActionListener{
    
        private JButton aButton,bButton,cButton,dButton;
        private Thread thread1,thread2;
        public static final int Width = 80;
        public static final int Height = 50;
        
        
        public Frame(){
            this.setSize(500,300);
            this.setResizable(false);
            this.setLocationRelativeTo(null);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            this.setLayout(null);
            
            
            aButton = new JButton("上传");
            aButton.setBounds(20, 150, Width, Height);
            
            bButton = new JButton("下载");
            bButton.setBounds(140, 150, Width, Height);
            
            cButton = new JButton("计算");
            cButton.setBounds(260, 150, Width, Height);
            cButton.setEnabled(false);//一开始禁用"计算"按钮
            
            dButton = new JButton("关于");
            dButton.setBounds(380, 150, Width, Height);
            
            aButton.addActionListener(this);
            bButton.addActionListener(this);
            cButton.addActionListener(this);
            dButton.addActionListener(this);        
            
            this.add(aButton);
            this.add(bButton);
            this.add(cButton);
            this.add(dButton);
                    
        }
        
        private void download(){
            
            try {
                Thread.sleep(6000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        private void upload(){
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        public static void main(String[] args) {
            new Frame().setVisible(true);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            String command = e.getActionCommand();
            if (command.equals("上传")) {
                aButton.setEnabled(false);
                aButton.setText("上传中");
            thread1= new Thread(()->{
                    upload();
                    aButton.setEnabled(true);
                    aButton.setText("上传");
                });
            thread1.start();
            }
            else if (command.equals("下载")) {
                bButton.setEnabled(false);
                bButton.setText("下载中");
                thread2 = new Thread(new Runnable() {
                    
                    @Override
                    public void run() {
                        download();
                        bButton.setEnabled(true);
                        bButton.setText("下载");                                      
                    }
                });
                thread2.start();
            }
            else if (command.equals("计算")) {
                
            }
            else if (command.equals("关于")) {
                JOptionPane.showMessageDialog(null, "load.....");
            }
            
            new Thread(() -> {
                if (thread1 != null && thread2 != null) {
                    try {
                    thread1.join();
                    thread2.join();
                    cButton.setEnabled(true);
                    }
                    catch (InterruptedException e1) {
                        e1.printStackTrace();
                    }
                }           
            }).start();
            
        }
    }
    

    线程同步

    • synchronized(隐式锁机制)有两种用法:
      1.放在方法的前面,该方法值允许抢占到对象锁的线程进入执行
      2.构造synchronized代码块(同步代码块),只允许抢占到对象锁的线程进入执行

    • Lock(显示锁机制)

    private Lock lock = new ReentrantLock();
    lock.lock();
    .....
    lock.unlock();
    
    • 没有抢占到对象锁的线程在系统自动维护的等锁池中等待
      如果抢到锁的线程释放了对象锁,那么这些等锁的线程就抢锁,谁抢到锁谁就进入同步代码块中执行,没有抢到的继续等待
      基于synchronized关键字的锁机制是可重入的锁机制

    • join方法是一个阻塞式方法,表示等待线程结束
      如果将join方法放到主线程,会导致其他线程被阻塞

    package org.mobiletrain;
    
    //import java.util.ArrayList;
    //import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    
    //线程同步问题
    class BankAccount {
    
        private double balance;
        private Lock lock = new ReentrantLock();
        
        public double getBalance() {        
            return balance;
        }
        
        //使用Java 5 以后的锁机制解决同步问题
        public /*synchronized*/ void transfer(double money){
            
            lock.lock();
            System.out.println(Thread.currentThread().getName());
            double newBalance = balance + money;
            try {
                Thread.sleep(1);
            } 
            catch (InterruptedException e) {
            }       
            balance = newBalance;   
            lock.unlock();
        }
    } 
    
    
    class AddMoneyHandler implements Runnable{
        
    
        private BankAccount account;
        private int money;
        
        public AddMoneyHandler(BankAccount account,int money) {
            this.account = account;
            this.money = money;
        }
        
        @Override
        public void run() {
            //synchronized (account) {
                account.transfer(money);
                
            //}
        }
        
    }
    
    public class Test01 {
    
        public static void main(String[] args) throws InterruptedException {
            //List<Thread> list = new ArrayList<>();
            ExecutorService service = Executors.newFixedThreadPool(10);
            BankAccount mainAccount = new BankAccount();
            for (int i = 0; i < 100; i++){
                service.execute(new AddMoneyHandler(mainAccount, 100));
                //Thread t = new Thread(new AddMoneyHandler(mainAccount, 100));
                //list.add(t);
                //t.start();
            }
            service.shutdown();
            //判断线程池里的线程有没有终止
            while ( ! service.isTerminated()) {
        
            }
            //join方法是一个阻塞式方法,表示等待线程结束
            //如果将join方法放到主线程,会导致其他线程被阻塞
            //for (Thread thread : list) {
                //线程对象的join()
                //thread.join();
            //}
            System.out.println("账户余额:¥" + mainAccount.getBalance());
        }
    }
    
    
    • wait()是让线程暂停(进入对象等待池),然后释放对象的锁 --- 在等待池中的线程需要其他线程将其唤醒

    • 设置优先级改变的是线程获得CPU调度的几率

    • 装潢模式
      将线程不安全的容器包装成线程安全的容器

    List<String> list = Collections.synchronizedList(new ArrayList<>());
    
    public static void main(String[] args) {
            List<String> list = Collections.synchronizedList(new ArrayList<>());
            //ArrayList是线程不安全的,因为它的方法没有加synchronized保护
            //List<String> list = new ArrayList<>();
            ExecutorService service = Executors.newFixedThreadPool(5);
            
            for (int i = 0; i < 5; i++){
                service.execute(new Runnable() {
                    
                    @Override
                    public void run() {                 
                        for (int j = 0; j < 100000; j++){                       
                        list.add("Hello");                                  
                        }                       
                    }
                });
            }
            service.shutdown();
            while (! service.isTerminated()){           
            }
            System.out.println(list.size());
        }       
    

    相关文章

      网友评论

          本文标题:Java -- 线程

          本文链接:https://www.haomeiwen.com/subject/plunvttx.html