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。。。(采用同步代码块和同步方法两种同步方法)的更多相关文章

  1. java线程基础巩固---同步代码块以及同步方法之间的区别和关系

    在上一次中[http://www.cnblogs.com/webor2006/p/8040369.html]采用同步代码块的方式来实现对线程的同步,如下: 对于同步方法我想都知道,就是将同步关键字声明 ...

  2. 对象及变量的并发访问(同步方法、同步代码块、对class进行加锁、线程死锁)&内部类的基本用法

    主要学习多线程的并发访问,也就是使得线程安全. 同步的单词为synchronized,异步的单词为asynchronized 同步主要就是通过锁的方式实现,一种就是隐式锁,另一种是显示锁Lock,本节 ...

  3. JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this

    JAVA之旅(十三)--线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this 我们继续上个篇幅接着讲线程的知识点 一.线程的安全性 当我们开启四个窗口(线程 ...

  4. Java基础8-多线程;同步代码块

    作业解析 利用白富美接口案例,土豪征婚使用匿名内部类对象实现. interface White{ public void white(); } interface Rich{ public void ...

  5. 线程执行synchronized同步代码块时再次重入该锁过程中抛异常,是否会释放锁

    一个线程执行synchronized同步代码时,再次重入该锁过程中,如果抛出异常,会释放锁吗? 如果锁的计数器为1,抛出异常,会直接释放锁: 那如果锁的计数器为2,抛出异常,会直接释放锁吗? 来简单测 ...

  6. Java 基础 线程的Runnable接口 /线程的同步方法 /同步代码块

    笔记: /**通过 Runnable接口来实现多线程 * 1. 创建一个实现runnable 接口的类 * 2. 在类中实现接口的run() 抽象方法 * 3. 创建一个runnable 接口实现类的 ...

  7. 廖雪峰Java11多线程编程-2线程同步-1同步代码块

    1.线程安全问题 多个线程同时运行,线程调度由操作系统决定,程序本身无法决定 如果多个线程同时读写共享变量,就可能出现问题 class AddThread extends Thread{ public ...

  8. 线程的同步机制:同步代码块&同步方法

    解决存在的线程安全问题:打印车票时出现重票,错票 使用同步代码块的解决方案 TestWindow2 package com.aff.thread; /* 使用实现Runnable接口的方式,售票 存在 ...

  9. 线程同步 synchronized 同步代码块 同步方法 同步锁

    一 同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块.其语法如下: synchronized(obj){ // ...

随机推荐

  1. 关东升的《iOS实战:图形图像、动画和多媒体卷(Swift版)》上市了

    关东升的<iOS实战:图形图像.动画和多媒体卷(Swift版)>上市了 承蒙广大读者的厚爱我的<iOS实战:图形图像.动画和多媒体卷(Swift版)>京东上市了,欢迎广大读者提 ...

  2. 新手之使用git

    本篇博客针对不会Git的小童鞋,大神们可以绕过,错误之处谢谢指正: 关于GitHub的强大此处不在说明,知道GitHub也有一段时间了,但是一直苦于不会使用. 本篇文章介绍的是如何将工程代码托管到上面 ...

  3. window子对象

    Window 子对象 (1)Location 对象 Location 对象包含有关当前 URL(统一资源定位符) 的信息.(Uniform Resource Location) Location 对象 ...

  4. Linux彻底删除mysql5.6

    查看安装的mysql组件 rpm -qa | grep -i mysql mysql57-community-release-el6-8.noarch mysql-community-common-5 ...

  5. Oracle 提供的start with 关键字用法

    在相关业务查询中,我们常常遇到相关的上下级关系情况,如下图中行政区划关联,此时就要用到Oracle 提供的start with 关键字来帮助我们进行递归查询 基本语法 SELECT ... FROM ...

  6. python函数的学习笔记

    这篇文章是我关于学习python函数的一些总结 一.随着函数的引入,这里首先要说的就是全局变量和局部变量了. 什么是全局变量.什么是局部变量: 全局变量就是全局都能调用的变量,一般都在文件的开头,顶头 ...

  7. linux安装jdk_1.8

    转载自http://blog.csdn.net/ldl22847/article/details/7605650 1.下载jdk的rpm安装包,这里以jdk-8u141-linux-x64.rpm为例 ...

  8. python学习之路-第二天-常见的注意事项(代码风格、运算符、优先级、控制语句)

    总结了今天学习几个注意事项: 对代码声明变量的时候没必要像以前写java或者c代码要声明数据类型,只需要赋值即可 代码一行基本只写一句逻辑行,而且尽量不在python里面写':' 明确的行连接'',暗 ...

  9. qemu-img 的使用

    qemu-img是QEMU的磁盘管理工具,在qemu-kvm源码编译后就会默认编译好qemu-img这个二进制文件.qemu-img也是QEMU/KVM使用过程中一个比较重要的工具,本节对其用法和实践 ...

  10. form 表单<input type="button" value="登录" onclick="loginSubmit ()"/> 点击提示 Uncaught TypeError: loginSubmit is not a function

    在网上搜了一堆东东,仔细看了一下,再加上实验,发现原因出在<form>中. <form method="post"> <button type=&qu ...