zoukankan      html  css  js  c++  java
  • Java多线程与并发——线程同步

    1.多线程共享数据

    在多线程的操作中,多个线程有可能同时处理同一个资源,这就是多线程中的共享数据。

    2.线程同步

    解决数据共享问题,必须使用同步,所谓同步就是指多个线程在同一时间段内只能有一个线程执行指定代码,其他线程要等待此线程完成之后才可以继续执行。

    线程进行同步,有以下两种方法:

    (1)同步代码块

    synchronized(要同步的对象){

          要同步的操作;

      }

    (2)同步方法

    public synchronized void method(){

          要同步的操作;

      }

    (3)Lock

    3.同步准则

    当编写synchronized快时,有几个简单的准则可以遵循,这些准则在避免死锁和性能危险的风险方面大有帮助:

    (1)使代码块保持简短。把不随线程变化的预处理和后处理移出synchronized快。

    (2)不要阻塞。如InputStream.read().

    (3)在持有锁的时候,不要对其它对象调用方法。

    package com.vince;
    
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 线程同步:1.同步代码块  2.同步方法  3.Lock
     * 同步会牺牲性能来换取安全
     * 
     * @author acer
     *
     */
    public class ThreadDemo {
    
    
        public static void main(String[] args) {
            MyThread mt=new MyThread();
            Thread t1=new Thread(mt);
            Thread t2=new Thread(mt);
            t1.start();
            t2.start();
        }
        
        
        static class MyThread implements Runnable{
            private int flag;
            private Object obj=new Object();
            
            public void run() {
                //同步代码块
                synchronized (obj) {
                    flag=0;
                    System.out.println("开始打饭"+flag);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO 自动生成的 catch 块
                        e.printStackTrace();
                    }
                    flag=1;
                    System.out.println("打饭结束"+flag);
                    
                }
                
            }
            //同步方法:同步的锁对象是当前对象
            public synchronized void eat(){
                flag=0;
                System.out.println("开始打饭"+flag);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO 自动生成的 catch 块
                    e.printStackTrace();
                }
                flag=1;
                System.out.println("打饭结束"+flag);
            }
            
            public synchronized void method(){
            System.out.println("method2...");
        }
            //互斥锁
            private final ReentrantLock lock=new ReentrantLock();
            public void eat2(){
                lock.lock();//上锁
                flag=0;
                System.out.println("开始打饭"+flag);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO 自动生成的 catch 块
                    e.printStackTrace();
                }
                flag=1;
                System.out.println("打饭结束"+flag);
                lock.unlock();//解锁
            }
            
    }
    }
  • 相关阅读:
    PTA 乙级 1064 朋友数 (20分) C++
    关于Symbol.iterator 学习笔记
    JS函数传递参数是是按值传递
    使用Nginx做反向代理的配置
    动态修改svg的颜色,svg做背景色时候修改颜色
    macos停止MySQL服务
    git-flow-avh的使用过程
    appium+rf APP自动化问题七----点击图片下方的文字无法实现页面跳转
    appium+rf 问题六--appium setting和unlock在设备上重复安装
    python3报错---Error in sitecustomize; set PYTHONVERBOSE for traceback: NameError: name 'reload' is not defined
  • 原文地址:https://www.cnblogs.com/shenhainixin/p/5138077.html
Copyright © 2011-2022 走看看