• 写2个线程,一个打印1-52,一个打印A-Z,打印顺序是12A34B。。。(采用同步代码块和同步方法两种同步方法)


    1.同步方法

    package Synchronized;
    /************************************同步方法****************************************/
    public class PrintTest {
    	public static void main(String[] args)
    	{
    		Print p = new Print();
    		Thread t1 = new PrintNumber(p);
    		Thread t2 = new PrintWord(p);
    		t1.start();
    		t2.start();
    	}
    }
    
    class PrintNumber extends Thread {//打印数字线程
    	private Print p;
    
    	public PrintNumber(Print p) {
    		this.p = p;
    	}
    
    	public void run() {
    		for (int i = 0; i < 26; i++) {
    			p.printNumber();
    		}
    	}
    }
    
    class PrintWord extends Thread {//打印字母线程
    	private Print p;
    
    	public PrintWord(Print p) {
    		this.p = p;
    	}
    
    	public void run() {
    		for (int i = 0; i < 26; i++) {
    			p.printWord();
    		}
    	}
    }
    
    class Print {             //同步监视器是Print类
    	private int i = 1;
    	private char j = 'A';
    
    	public Print() {
    	}
    
    	public synchronized void printNumber() {//同步方法
    		System.out.print(String.valueOf(i) + String.valueOf(i + 1));
    		i += 2;
    		notifyAll();      //先唤醒其他进程,再阻塞本进程,如果顺序颠倒了,进程阻塞后不能再唤醒其他进程
    		try {
    			wait();
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    
    	public synchronized void printWord() {
    		System.out.print(j);
    		j++;
    		notifyAll();
    		try
    		{
    			if (j <= 'Z')//输出Z之后就不用再等待了。
    			{
    
    				wait();
    			}
    		} 
    		catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    
    	}
    }
    

     2.同步代码块package threaddemo;

    
    /**
     * <写两个线程,一个线程打印1-52,另一个线程打印字母A-Z。打印 顺序为12A34B56C……5152Z>
     * 
     */
    /*****************************************同步代码块*********************************************/ public class ThreadDemo { // 测试 public static void main(String[] args) throws Exception { Object obj = new Object(); // 启动两个线程 Thread1 t1 = new Thread1(obj); Thread2 t2 = new Thread2(obj); t1.start(); t2.start(); } } // 一个线程打印1-52 class Thread1 extends Thread { private Object obj; public Thread1(Object obj) { this.obj = obj; } public void run() { synchronized (obj) { // 打印1-52 for (int i = 1; i < 53; i++) { System.out.print(i + " "); if (i % 2 == 0) { // 不能忘了 唤醒其它线程 obj.notifyAll(); try { obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } // 另一个线程打印字母A-Z class Thread2 extends Thread { private Object obj; public Thread2(Object obj) { this.obj = obj; } public void run() { synchronized (obj) //同步监视器是obj类,同步代码块是写在run方法里面的。 { // 打印A-Z for (int i = 0; i < 26; i++) { System.out.print((char)('A' + i) + " "); // 不能忘了 唤醒其它线程 obj.notifyAll(); try { // 最后一个就不要等了 if (i != 25) { obj.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } } } } }

     下面是我后来写的。自习区分一下,因为主程序只有两个线程相互交替,所以是没有必要设置flag的。只有很多进程交互的时候,才有必要设置flag,并且我是通过flag来判断切换进程的,所以循环次数是52次,而不是26次。

    public class test1 
    {
    	public static void main(String[] args) {
    		Print p = new Print();
    		new PrintNumber(p).start();
    		new PrintWord(p).start();
    	}
    }
    class Print
    {
    	private boolean flag = false;
    	public int num = 1;
    	public char chr = 'A';
    	public synchronized void printNumber()
    	{
    		try
    		{
    			if(flag)
    			{
    				if(num <= 52)
    				{
    					wait();
    				}
    			}
    			else
    			{
    				System.out.print(num);
    				System.out.print(num + 1);
    				num += 2;
    				flag = true;
    				notify();
    			}
    		}
    		catch(InterruptedException ie)
    		{
    			ie.printStackTrace();
    		}
    	}
    	
    	public synchronized void printWord()
    	{
    		try
    		{
    			if(!flag)
    			{
    				if(chr <= 'Z')
    				{
    					wait();
    				}
    			}
    			else
    			{
    				System.out.print(chr);
    				chr += 1;
    				flag = false;
    				notify();
    			}
    		}
    		catch(InterruptedException ie)
    		{
    			ie.printStackTrace();
    		}
    	}
    }
    class PrintNumber extends Thread
    {
    	Print p;
    	PrintNumber(Print p)
    	{
    		this.p = p;
    	}
    	public void run()
    	{
    		for(int i = 0; i < 52; i ++)
    		{
    			p.printNumber();
    		}
    	}
    }
    class PrintWord extends Thread
    {
    	Print p;
    	PrintWord(Print p)
    	{
    		this.p = p;
    	}
    	public void run()
    	{
    		for(int i = 0; i < 52; i ++)
    		{
    			p.printWord();
    		}
    	}
    }
    

     实现Runnable接口

    public class test2 {
    	public static void main(String[] args) {
    		Print p = new Print();
    		new Thread(new Runnable() {
    			
    			@Override
    			public void run() {
    				// TODO Auto-generated method stub
    				for(int i = 0; i < 26; i ++)
    				{
    					p.printNum();
    				}
    			}
    		}).start();
    		new Thread(new Runnable() {
    			
    			@Override
    			public void run() {
    				// TODO Auto-generated method stub
    				for(int i = 0; i < 26; i ++)
    				{
    					p.printWord();
    				}
    			}
    		}).start();
    	}
    }
    class Print
    {
    	char chr = 'A';
    	int num = 1;
    	public synchronized void printNum()
    	{
    		System.out.print(num);
    		System.out.print(num + 1);
    		num += 2;
    		notify();
    		try{
    			wait();
    		}
    		catch(InterruptedException ie)
    		{
    			ie.printStackTrace();
    		}
    				
    	}
    	public synchronized void printWord()
    	{
    		System.out.print(chr);
    		chr += 1;
    		notify();
    		try{
    			if(chr <= 'Z')
    			wait();
    		}
    		catch(InterruptedException ie)
    		{
    			ie.printStackTrace();
    		}
    	}
    }
    
  • 相关阅读:
    Python学习小目录汇总
    进制转换的知识
    计算机组成原理目录
    python基础知识-8-三元和一行代码(推导式)
    python基础知识-7-内存、深浅、文件操作
    IT工具使用
    Python基础知识-06-集合内存布尔False
    Python基础知识-05-数据类型总结字典
    elk收集tomcat日志
    pycharm重命名文件
  • 原文地址:https://www.cnblogs.com/masterlibin/p/4800297.html
Copyright © 2020-2023  润新知