精华内容
下载资源
问答
  • 交替打印奇偶数
    2022-04-09 06:11:26

    Golang 面试题 (1) 用协程交替打印奇偶数

    面试神策数据时,有被问到,答得不太好,记录一下

    方法1

    • 两个G,分别打印奇数和偶数
    • 无缓冲channel通知这两个G,控制打印顺序
    var flagChan=make(chan int)
    
    func wokr1(){
    	for i:=1;i<=100;i++{
    		flagChan <- 1 //塞入
    		if i%2==1{
    			fmt.Println(i)
    		}
    	}
    }
    
    func wokr2(){
    	for i:=1;i<=100;i++{
    		_= <- flagChan // 取出
    		if i%2==0{
    			fmt.Println(i)
    		}
    	}
    }
    
    
    func main() {
    	go wokr1()
    	go wokr2()
    
    	time.Sleep(3*time.Second)
    }

    方法2:

    • 一个channel存储要打印的数据
    • 一个channel通知两个协程打印
    • 注意:采用的是无缓冲channel,不能采用缓存大小为1的channel,因为无限缓存的channle塞入时会一直阻塞,知道在另一个G中被取,同样,取也会一直阻塞,直到在另一个G中被塞入
    var flagChan=make(chan int)
    var ch=make(chan int,100)
    
    func wokr1(){
    	for{
    		flagChan <- 1 //塞入
    		x:= <- ch
    		fmt.Println(x)
    	}
    }
    
    func wokr2(){
    	for {
    		_= <- flagChan // 取出
    		y:=<-ch
    		fmt.Println(y)
    	}
    }
    
    
    func main() {
    	for i:=1;i<=100;i++{
    		ch <- i
    	}
    	go wokr1()
    	go wokr2()
    
    	time.Sleep(3*time.Second)
    }

    注意:G之间的同步请采用无缓冲的channel,不要采用有缓冲的channel

    更多相关内容
  • 主要介绍了Java 实现多线程切换等待唤醒交替打印奇偶数 ,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • Java两个线程交替打印奇偶数(两种方法对比)

    千次阅读 热门讨论 2020-10-31 15:11:20
    我们将通过“两个线程交替打印100内的奇偶数”,来展示下`wait()`方法和`notify()`方法的用法和优点,当然要体现出优点,自然要通过对比不使用这两个方法实现同一功能的代码,通过这几篇文章的讲解,帮你彻底搞懂`...

    简介

    本文将承接文章《Java多线程wait()和notify()系列方法使用教程》,我们将通过“两个线程交替打印100内的奇偶数”,来展示下wait()方法和notify()方法的用法和优点,当然要体现出优点,自然要通过对比不使用这两个方法实现同一功能的代码,通过这几篇文章的讲解,帮你彻底搞懂wait()方法和notify()方法的用法。

    一.仅通过synchronized关键字实现交替打印奇偶数

    1.实现逻辑:

    创建两个线程,一个线程负责打印奇数,另一个线程打印偶数,两个线程竞争同一个对象锁,每次打印一个数字后释放锁,然后另一个线程拿到锁打印下一个数字。

    2.代码实现:

    public class PrintOddEven1 {
    	private static int count;
    
    	private static final Object object = new Object();
    
    	public static void main(String[] args) {
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while (count < 100) {
    					synchronized (object) {
    						if ((count & 1) == 0) {
    							System.out.println(Thread.currentThread().getName() + ":" + count++);
    						}
    					}
    				}
    
    			}
    		}, "偶数线程").start();
    
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while (count < 100) {
    					synchronized (object) {
    						if ((count & 1) == 1) {
    							System.out.println(Thread.currentThread().getName() + ":" + count++);
    						}
    					}
    				}
    
    			}
    		}, "奇数线程").start();
    	}
    
    }
    

    3.结果输出:

    偶数线程:0
    奇数线程:1
    偶数线程:2
    奇数线程:3
    偶数线程:4
    奇数线程:5
    偶数线程:6
    奇数线程:7
    偶数线程:8
    奇数线程:9
    偶数线程:10
    

    4.结果分析:

    通过创建两个线程,这两个线程共享object对象锁,当一个线程打印完一个数字后,会释放对象锁,另一个线程拿到对象锁,然后判断是否为偶数(奇数),满足条件则打印。

    二.通过synchronized关键字配合wait和notify方法实现交替打印奇偶数

    1.实现逻辑:

    无需判断数字是否是奇偶数,两个线程通过等待唤醒机制,交替打印数字。

    2.代码实现:

    public class PrintOddEven2 {
    
    	private static int count = 0;
    	private static final Object object = new Object();
    
    	public static void main(String[] args) {
    		new Thread(new printer(), "偶数线程,").start();
    		new Thread(new printer(), "奇数线程,").start();
    	}
    
    	static class printer implements Runnable {
    
    		@Override
    		public void run() {
    			while (count <= 100) {
    				synchronized (object) {
    					// 打印数字,并立即释放锁
    					System.out.println(Thread.currentThread().getName() + "打印:" + count++);
    					object.notify();
    					// 此处判断,是为了打印完了100个数字后,程序能够正常结束,否则程序将一直等待下去,耗费系统资源。
    					if (count <= 100) {
    						try {
    							object.wait();
    						} catch (InterruptedException e) {
    							e.printStackTrace();
    						}
    					}
    				}
    			}
    		}
    	}
    
    }
    
    
    

    3.结果输出:

    偶数线程,打印:0
    奇数线程,打印:1
    偶数线程,打印:2
    奇数线程,打印:3
    偶数线程,打印:4
    奇数线程,打印:5
    偶数线程,打印:6
    奇数线程,打印:7
    偶数线程,打印:8
    奇数线程,打印:9
    偶数线程,打印:10
    ……省略
    

    4.结果分析:

    此种方式,写法简洁,让线程拿到对象锁后,立即打印数字,然后通过notify()释放锁,然后调用wait()方法使线程进入等待状态。另一个线程拿到锁以后,也立即打印数字,然后通过notify()释放锁,然后进入等待状态。知道打印完100以内的所有数字,两个线程都能正常停止运行。

    总结

    本文作为wait()notify()方法的用法示例教程,展示wait()notify()方法的用法,下一篇文章将再展示一个wait()notify()方法的使用案例《设计模式之消费者生产者模式》,将带大家继续领悟下线程唤醒通知机制使用意义所在。

    建议收藏:

    关于synchronized关键字wait()notify()方法的系列教程,请参考以下文章:

    《Java中synchronized实现类锁的两种方式及原理解析》

    《Java中synchronized实现对象锁的两种方式及原理解析》

    《Java多线程wait()和notify()系列方法使用教程》

    《Java多线程中notifyAll()方法使用教程》

    《Java中Synchronized的可重入性和不可中断性的分析和代码验证》

    《Java多线程访问Synchronized同步方法的八种使用场景》

    《Java官方文档创建线程的两种方式及优点和缺点分析》

    《Java中线程安全和线程不安全解析和示例》

    展开全文
  • 线程交替打印奇偶数涉及到的三个方法: 涉及到的三个方法: wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。 notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就...

    线程交替打印奇偶数

    涉及到的三个方法:

    • wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器。
    • notify():一旦执行此方法,就会唤醒被wait的一个线程。如果有多个线程被wait,就唤醒优先级高的那个。
    • notifyAll():一旦执行此方法,就会唤醒所有被wait的线程。

    **** 说明:***
    1.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中。
    2.wait(),notify(),notifyAll()三个方法的调用者必须是同步代码块或同步方法中的同步监视器。否则,会出现IllegalMonitorStateException异常
    3.wait(),notify(),notifyAll()三个方法是定义在java.lang.Object类中。

    class Num1 implements Runnable {
        private Test1 ticket;
    
        public Num1(Test1 ticket) {
            this.ticket = ticket;
        }
        @Override
        public void run() {
            while (ticket.num>0) {
                synchronized (ticket) {
                    if(ticket.num%2==0){
                        try {
                            ticket.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else{
                        System.out.println(Thread.currentThread().getName()+":"+ticket.num);
                        ticket.num--;
                        ticket.notify();
                    }
                }
            }
        }
    }
    class Num2 implements Runnable {
        private Test1 ticket;
    
        public Num2(Test1 ticket) {
            this.ticket = ticket;
        }
        @Override
        public void run() {
            while (ticket.num>0) {
                synchronized (ticket) {
                    if(ticket.num%2!=0){
                        try {
                            ticket.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else{
                        System.out.println(Thread.currentThread().getName()+":"+ticket.num);
                        ticket.num--;
                        ticket.notify();
                    }
                }
            }
        }
    }
    public class Test1 {
        public int num=100;
    
        public static void main(String[] args) {
            Test1 ticket = new Test1();
            Num1 n1=new Num1(ticket);
            Thread t1=new Thread(n1);
            Num2 n2=new Num2(ticket);
            Thread t2=new Thread(n2);
            t1.setName("奇数项");
            t2.setName("偶数项");
            t1.start();
            t2.start();
    
        }
    }
    
    
    展开全文
  • 序言以前看过多线程交替打印奇偶数,知道大概怎么写,实际写的时候会卡住,特此记录下来方法一:wait, notify,性能较差,不推荐使用public class TestThread {public static int i = 1;public static final int ...

    序言

    以前看过多线程交替打印奇偶数,知道大概怎么写,实际写的时候会卡住,特此记录下来

    方法一:wait, notify,性能较差,不推荐使用

    public class TestThread {

    public static int i = 1;

    public static final int TOTAL = 100;

    public static Object lock = new Object();

    public static void main(String[] args) {

    Thread thread1 = new Thread(() -> {

    while (i <= TOTAL) {

    synchronized (lock) {

    if (i % 2 == 1) {

    System.out.println("i=" + i++);

    lock.notify();

    } else {

    try {

    lock.wait();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    }

    });

    Thread thread2 = new Thread(() -> {

    while (i <= TOTAL) {

    synchronized (lock) {

    if (i % 2 == 0) {

    System.out.println("i=" + i++);

    lock.notify();

    } else {

    try {

    lock.wait();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    }

    });

    thread1.start();

    thread2.start();

    }

    }

    方法二:countDownLatch,推荐使用

    public class TestThread2 {

    private static AtomicInteger num = new AtomicInteger(1);

    private static CountDownLatch countDownLatch = new CountDownLatch(2);

    public static void main(String[] args) throws InterruptedException {

    Thread t1 = new Thread() {

    @Override

    public void run() {

    while (num.intValue() < 100) {

    if (num.intValue() % 2 == 1) {

    System.out.println("奇数线程:"+num.intValue());

    num.incrementAndGet();

    }

    countDownLatch.countDown();

    }

    }

    };

    Thread t2 = new Thread() {

    @Override

    public void run() {

    while (num.intValue() <= 100) {

    if (num.intValue() % 2 == 0) {

    System.out.println("偶数线程:"+num.intValue());

    num.incrementAndGet();

    }

    countDownLatch.countDown();

    }

    }

    };

    t1.start();

    t2.start();

    countDownLatch.await();

    }

    }

    展开全文
  • 引言java面试中经常会遇到这个问题,如何用两个线程交替打印奇偶数。线程A打印1,线程B打印2,线程A打印3,线程B打印4...这个问题的解题思路是协调两个线程的执行时机,线程A与线程B需要交替执行。实现的方式很多,...
  • @C#使用信号量实现交替打印奇偶数 Semaphore(信号量) 允许多个线程同时访问一个共享资源 通过使用一个计数器来控制对共享资源的访问,如果计数器大于0,就允许访问,如果等于0,就拒绝访问。计数器累计的是“许可...
  • } } } 点评:可拓展性实现2相对较差一些(实现3个线程交替打印etc) Synchronized + wait/notify实现public class Main{ public static void main(String[] args){ MyPrint print = new MyPrint(); Thread thread1 = ...
  • 思路:利用Object.wait()和Object.notify()方法进行线程间的通信。 代码: public class MyThread implements Runnable { private static int i = 1; private byte[] s1; public MyThread(byte[]... this.s...
  • Java交替打印奇偶数

    2020-11-02 11:25:25
    这个算法需要解决两个问题:怎么实现交替打印?怎么实现奇偶数? 算法一:(互斥实现)用一个自增的数,依次对2取余,来实现奇偶数。然后,用信号量(信号量底层用原语实现互斥同步,很方便,大家可以去了解一下,...
  • * Description: 使用等待唤醒机制打印奇数偶数 -- while循环的方式 * 注意: * 1.必须指明是object对象在调用notify和wait方法,不指明默认就是this-当前对象(那你代码肯定跑不起来) (i)我们锁的对象是...
  • 实现思想主要是让两个线程互相唤醒对方来交替打印数字 #include <unistd.h> #include <stdlib.h> #include <pthread.h> #include <stdio.h> int g_num = 1; pthread_mutex_t mutex; ...
  • #include<iostream> #include<mutex> #include<thread> #include<condition_variable> #include<Windows.h> using namespace std; mutex mut; condition_variable cond1, cond2;... un
  • 里面提到了:两个线程,交替打印奇偶数这道笔试题。update on 2020/6/7,下面的第二种方式,现在回头看,其实感觉写得不好,下面直接贴一种更直接的方式(目前的技术水平写的,应该比之前的写的好点)。1 @Slf4j2 ...
  • 构造两个线程,交替打印1-100之间的数字,其中线程1打印奇数,线程2打印偶数。 方式1:采用synchronized同步锁和wait,notify线程通信机制来实现。 public class jiaotidayinshuzi { public static void main...
  • System.out.println("偶数" + "+-+" +number.start); number.start++; number.flag= false; }finally{ LOCK.unlock(); } } } } }public static class JiNum implementsRunnable {privateSolution number;...
  • C++11双线程交替打印奇偶数
  • 两个协程交替打印1-100的奇偶数,一个协程打印奇数,一个协程打印偶数。 代码1: package main import ( "fmt" "runtime" "time" ) func main() { //设置可同时使用的CPU核数为1 runtime.GOMAXPROCS(1) ...
  • * java 2个线程交替打印奇偶数 * @author Administrator * */ public class Main { public static void main(String[] args) { Print p=new Print(); Thread a=new Thread(p,"A");//A打印偶数 ...
  • * @Description 交替打印奇偶数 notify实现 * @Version 1.0 */ public class AlternatePrintingNotifyAndWait { private static Object object = new Object(); private static int i = 0; public static...
  • public classOddEven {intlen;int[] num;int idx = 0;final Boolean lock = false;ReentrantLock rlock= newReentrantLock();public OddEven(intlen) {this.len =len;num= new int[len];for (int i = 0;...
  • 多线程:两个线程交替打印奇偶数

    千次阅读 2018-08-22 14:17:35
    要求:两个线程交替打印从1到100的数字。
  • 关于ReentrantLock的实现...用ReentrantLock实现交替打印奇偶数,就是开两个线程,一个打印奇数,一个用于打印偶数。 为什么要用ReentrantLock呢,因为这里交替打印(线程交替执行),需要对共享变量flag进行反复...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 843
精华内容 337
关键字:

交替打印奇偶数