zoukankan      html  css  js  c++  java
  • 多线程的一些问题

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

    1.使用同步代码块的方法解决同步线程的安全问题

    package com.lanqiao.javatest;
    /*
    * 线程的同步,安全问题:打印车票出现重票,错票
    * */
    //存在安全性问题的原因是什么:

    //使用同步代码块的方法实现进程同步出现的数据输出重复,不规范的问题
    class Win extends Thread{
    static int ticket=100;
    Object obj=new Object();
    public void run(){
    while(true){
    synchronized (obj) {//this,当前方法的对象
    try {
    sleep(100);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    if(ticket>0){
    System.out.println(Thread.currentThread().getName()+":"+ticket--);
    }

    }
    }
    }
    }

    public class ThreadTest {
    public static void main(String[] args) {
    Win w1=new Win();
    Win w2=new Win();
    Win w3=new Win();

    w1.setPriority(Thread.MAX_PRIORITY);
    w2.setPriority(Thread.NORM_PRIORITY);
    w3.setPriority(Thread.MIN_PRIORITY);

    w1.setName("线程1:");
    w2.setName("线程2:");
    w3.setName("线程3:");

    w1.start();
    w2.start();
    w3.start();
    }
    }

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

    2.使用同步方法,解决同步线程的程安全问题

    package com.lanqiao.javatest;


    //使用同步方法,解决进程同步问题
    //在多线程中,当一个线程操作执行时,其他线程不能进入进行操作,直至此线程执行完后,其他线程才可以进入进行操作;
    class Win1 extends Thread{
    Object obj=new Object();
    static int ticket=100;
    public void run(){
    while(true){
    shou();
    }
    }
    public synchronized void shou(){

    try {
    sleep(100);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    if(ticket>0){
    System.out.println(Thread.currentThread().getName()+":"+ticket--);
    }
    }
    }
    public class ThreadTest1 {
    public static void main(String[] args) {
    Win1 w1=new Win1();
    Win1 w2=new Win1();
    Win1 w3=new Win1();

    w1.setPriority(Thread.MAX_PRIORITY);
    w2.setPriority(Thread.NORM_PRIORITY);
    w3.setPriority(Thread.MIN_PRIORITY);

    w1.setName("线程1:");
    w2.setName("线程2:");
    w3.setName("线程3:");

    w1.start();
    w2.start();
    w3.start();
    }
    }

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

     3.同步代码块中使用wait(),notify(),notifyAll()[必须在同步代码块使用这三个方法]

    package com.lanqiao.javatest;
    //线程同步:wait():线程挂起,并且放弃cpu资源,不同于,sleep(线程挂起一段时间,时间一到继续抢夺cpu);
    //notify(),notifyAll():唤醒被挂起的线程,使其继续抢夺cpu;
    //三个方法使用时,必须在同步代码块或同步方法中实现
    //练习:有两个线程一个一个的输出100之内的数
    class Test implements Runnable{
    static int num=1;
    @SuppressWarnings("static-access")
    @Override
    public void run() {
    while(true){
    synchronized (this) {
    notify();
    try {
    Thread.currentThread().sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    if (num <= 100) {
    System.out.println(Thread.currentThread().getName() + ":" + num);
    num++;
    } else {
    break;
    }
    try {
    wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }
    }

    }

    }
    public class ThreadTest2 {
    public static void main(String[] args) {
    Test t=new Test();

    Thread t1=new Thread(t);
    Thread t2=new Thread(t);

    t1.setName("线程1:");
    t2.setName("线程2:");

    t1.start();
    t2.start();
    }
    }

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

    4.同步线程的练习题:

    (1)例题1:两个用户向同一账户中存钱,每人存钱三次,每次1000元

    package com.lanqiao.javatest;
    /*
    * 练习:两个用户向同一账户中存钱,每人存钱三次,每次1000元
    * 其中,建立类时:每个类中都有有参数或无参数的构造方法;然后有几个变量,方法实现
    * */
    class Account{
    double balance=189;
    public Account(){

    }
    //找共享数据时,加synchronized是,看变量balance在什么地方变换
    public synchronized void deposit(double money){
    balance+=money;
    try {
    Thread.currentThread().sleep(100);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+":"+balance);
    }
    }
    class Customer extends Thread{
    Account account;
    public Customer(Account account){
    this.account=account;
    }
    public void run(){
    for(int i=0;i<3;i++){
    account.deposit(1000);
    }

    }
    }

    public class ThreadTest3 {
    public static void main(String[] args) {
    Account aa=new Account();

    Customer c=new Customer(aa);
    Customer d=new Customer(aa);

    c.setName("线程1:");
    d.setName("线程2:");

    c.start();
    d.start();
    }
    }

    (2)例题2:生产者和消费者的问题

    package com.lanqiao.javatest;
    /*
    *生产者和消费者的问题
    *生产者:生产的产品超过20了,就停止生产,直到消费者使产品小于等于20时,再进行生产
    *消费者:不断的消费产品
    *店员:通过产品剩余的多少,
    *少于等于20时,向消费者提供产品,
    *大于20时,向生产者提出停产的通知,
    *小于0时,向消费者提出没有产品了请等待;
    *
    * */
    class Clerk{//店员
    int produce;//不加值的话是从0开始的
    public Clerk(){

    }
    public synchronized void addProduce(){//生产者生产

    if(produce>=20){
    try {
    wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    else{
    produce++;
    System.out.println(Thread.currentThread().getName()+":生产了第"+produce+"个产品");
    notifyAll();
    }
    }
    public synchronized void subCustomerww(){//消费者消费
    if(produce<=0){
    try {
    wait();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    else{

    System.out.println(Thread.currentThread().getName()+":消费了第"+produce+"个产品");
    produce--;
    notifyAll();
    }
    }
    }

    class Producer implements Runnable{//生产者
    Clerk clerk;
    public Producer(){}
    public Producer(Clerk clerk){
    this.clerk=clerk;
    }
    @SuppressWarnings("static-access")
    public void run() {
    System.out.println("生产者生产产品:");
    while(true){
    try {
    Thread.currentThread().sleep(200);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    clerk.addProduce();
    }
    }
    }
    class Customerww implements Runnable{//消费者
    Clerk clerk;
    public Customerww(){

    }
    public Customerww(Clerk clerk){
    this.clerk=clerk;
    }

    @SuppressWarnings("static-access")
    public void run() {
    System.out.println("消费者消费产品:");
    while(true){
    try {
    Thread.currentThread().sleep(200);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    clerk.subCustomerww();
    }
    }

    }
    public class ThreadTest4 {
    public static void main(String[] args) {
    Clerk clerk=new Clerk();

    Producer p=new Producer(clerk);
    Customerww c=new Customerww(clerk);

    Thread t1=new Thread(p);
    Thread t2=new Thread(c);

    t1.setName("线程1:");
    t2.setName("线程2:");

    t1.start();
    t2.start();
    }
    }

  • 相关阅读:
    RuntimeError: cryptography is required for sha256_password or caching_sha2_p
    Django-C003-视图
    MySQL 实时监控日志
    ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061) : 第一次设置MySQL也适用
    Django-C002-深入模型,到底有多深
    ubuntu16.04下安装&配置anaconda+tensorflow新手教程
    人脸算法系列:MTCNN人脸检测详解
    YOLO系列:YOLOv1,YOLOv2,YOLOv3,YOLOv4,YOLOv5简介
    python __getitem__()方法理解
    启动scala的方法
  • 原文地址:https://www.cnblogs.com/lxnlxn/p/5764477.html
Copyright © 2011-2022 走看看