写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();
}
}
}
写2个线程,一个打印1-52,一个打印A-Z,打印顺序是12A34B。。。(采用同步代码块和同步方法两种同步方法)的更多相关文章
- java线程基础巩固---同步代码块以及同步方法之间的区别和关系
在上一次中[http://www.cnblogs.com/webor2006/p/8040369.html]采用同步代码块的方式来实现对线程的同步,如下: 对于同步方法我想都知道,就是将同步关键字声明 ...
- 对象及变量的并发访问(同步方法、同步代码块、对class进行加锁、线程死锁)&内部类的基本用法
主要学习多线程的并发访问,也就是使得线程安全. 同步的单词为synchronized,异步的单词为asynchronized 同步主要就是通过锁的方式实现,一种就是隐式锁,另一种是显示锁Lock,本节 ...
- JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this
JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程 ...
- Java基础8-多线程;同步代码块
作业解析 利用白富美接口案例,土豪征婚使用匿名内部类对象实现. interface White{ public void white(); } interface Rich{ public void ...
- 线程执行synchronized同步代码块时再次重入该锁过程中抛异常,是否会释放锁
一个线程执行synchronized同步代码时,再次重入该锁过程中,如果抛出异常,会释放锁吗? 如果锁的计数器为1,抛出异常,会直接释放锁: 那如果锁的计数器为2,抛出异常,会直接释放锁吗? 来简单测 ...
- Java 基础 线程的Runnable接口 /线程的同步方法 /同步代码块
笔记: /**通过 Runnable接口来实现多线程 * 1. 创建一个实现runnable 接口的类 * 2. 在类中实现接口的run() 抽象方法 * 3. 创建一个runnable 接口实现类的 ...
- 廖雪峰Java11多线程编程-2线程同步-1同步代码块
1.线程安全问题 多个线程同时运行,线程调度由操作系统决定,程序本身无法决定 如果多个线程同时读写共享变量,就可能出现问题 class AddThread extends Thread{ public ...
- 线程的同步机制:同步代码块&同步方法
解决存在的线程安全问题:打印车票时出现重票,错票 使用同步代码块的解决方案 TestWindow2 package com.aff.thread; /* 使用实现Runnable接口的方式,售票 存在 ...
- 线程同步 synchronized 同步代码块 同步方法 同步锁
一 同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块.其语法如下: synchronized(obj){ // ...
随机推荐
- 记录--java 分页 思路 (hibernate关键代码)
有时会脑袋蒙圈,记录下分页的思路 下面代码是hibernate的分页,其分页就是从第几条数据为起点,取几条数据.比如在mysql中的limit(5,10)取的就是第6条到第10条 在下面代码中的pag ...
- php7/etc/php-fpm.d 配置
php7/etc/php-fpm.d/www.conf nginx php-fpm 高并发优化 - 日记本的回忆 - 博客园 https://www.cnblogs.com/cocoliu/p/856 ...
- Cookies with curl the command line tool
w https://curl.haxx.se/docs/http-cookies.html curl has a full cookie "engine" built in. If ...
- 问题:Unable to find a 'userdata.img' file for ABI armeabi to copy into the AVD folder.
创建AVD时,发现创建不成功,报错“Unable to find a 'userdata.img' file for ABIarmeabi to copy into the AVD folder.” ...
- gnu libiconv(可以下载)
Chinese EUC-CN, HZ, GBK, CP936, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, BIG5-HKSCS:2004, BIG5-HKSC ...
- SQL判断字符类型是否为数字
用ISNUMERIC函数 确定表达式是否为一个有效的数字类型. 语法 ISNUMERIC ( expression ) 参数 expression 要计算的表达式. 返回类型 int 注释 当输入表达 ...
- 老铁,这年头不会点git真不行
作者:武沛齐 出处:http://www.cnblogs.com/wupeiqi/ 版本控制 说到版本控制,脑海里总会浮现大学毕业是写毕业论文的场景,你电脑上的毕业论文一定出现过这番景象! 毕业论文_ ...
- HDFS权限管理指南(HDFS Permissions Guide)
综述 HDFS实现了一个类似POSIX模型的文件和文件夹权限管理模型.每一个文件盒文件夹都有一个所有者和一个组.文件或者文件夹可以通过权限区分是所有者还是组成员或是其他用户.对文件来说,r标示可以阅读 ...
- 001-maven下载jar后缀为lastUpdated问题
问题简述 Maven在下载仓库中找不到相应资源时,网络中断等,会生成一个.lastUpdated为后缀的文件.如果这个文件存在,那么即使换一个有资源的仓库后,Maven依然不会去下载新资源. 解决方案 ...
- 《Mining of Massive Datasets》笔记(一)
数据挖掘基本概念 数据挖掘定义 最广为接受得到定义是,数据挖掘是数据"模型"的发现过程.而"模型"却可以有多种含义. 1)统计建模 统计学家认为数据挖掘就是统计 ...