Java——多线程小例子
body, table{font-family: 微软雅黑; font-size: 10pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}
两种实现方式的对比:
解决问题:
|
格式:
Synchronized(对象){ //让这里的代码变成一个原子操作,不会再代码块的某一个地方切换到其他线程;对象可以是Object
需同步代码块
}
|
| MainClass.java | |
|
package com.java.ticket;
public class MainClass {
public static void main(String[] args) {
//方法一
Window window1=new Window(100);
Window window2=new Window(100);
Window window3=new Window(100);
window1.start();
window2.start();
window3.start();
//方法二 sellTicket共享,就不用把ticket声明成静态的 ; 同样,没有互斥
/* SellTicket sellTicket=new SellTicket();
Thread t1=new Thread(sellTicket,"窗口1"); //用同一个对象初始化三个线程,并每个线程命名
Thread t2=new Thread(sellTicket,"窗口2");
Thread t3=new Thread(sellTicket,"窗口3");
t1.start();
t2.start();
t3.start();*/
}
}
|
|
| Window.java | SellTicket.java |
|
package com.java.ticket;
public class Window extends Thread {
static int ticket;
Object object=new Object();
public void run() {
super.run();
while(ticket>0){
//卖票
//方式一:
/* synchronized (object){
sell();
}*/
//方式二
sell();
}
}
/* void sell(){
if(ticket>0){
System.out.println(getName()+"卖出第 "+ticket--+" 张票"); //执行这条语句的同时,共享数据自减
}
}*/
public synchronized void sell(){ //最佳
if(ticket>0){
System.out.println(getName()+"卖出第 "+ticket--+" 张票"); //执行这条语句的同时,共享数据自减,属于一个原子操作
}
}
public Window(int ticket) {
super();
this.ticket = ticket;
}
}
|
package com.java.ticket;
public class SellTicket implements Runnable {
Object object=new Object();
int ticket=100;
public void run() {
//synchronized(object){ //让这里的代码变成一个原子操作,不会再代码块的某一个地方挂起切换到其他线程
//同步语句在这里就只有一个窗口卖票,其他窗口无法打断
while(ticket>0){
//出现卖负票是因为在这里挂起
//synchronized(object){ //同步语句加在这里,会出现卖负票
synchronized(object){ //括号里(new Object)就不行,会出现多张相同的票;因为每个线程调用run方法,都会new一个对象,多个线程就会有多个锁
//这里object也可以是this,因为三个线程都是用同一个对象来初始化的,所以obj也不用声明成静态的
if(ticket>0){
System.out.println(Thread.currentThread().getName()+"卖出第 "+ticket--+" 张票");
//ticket--;
}
}
}
}
}
|
| test1.java | test2.java |
|
package com.java.threadExercise;
import java.util.Random;
public class test2 {
/**
* 创建一个任务,它将睡眠1到10秒之间的随机数量的时间,
* 然后显示它的睡眠时间并退出。创建并运行多个这种任务。
*/
public static void main(String[] args) {
Thread1 t1=new Thread1("No.1");
Thread1 t2=new Thread1("No.2");
Thread1 t3=new Thread1("No.3");
t1.start();
t2.start();
try {
t2.join(); //等待线程t2执行完毕才会执行下面的语句;开始t3线程
} catch (InterruptedException e) {
e.printStackTrace();
}
t3.start();
}
}
class Thread1 extends Thread {
public Thread1(String string){
super(string);
}
public void run(){
super.run();
Random r1=new Random();
int i=r1.nextInt(11)*1000; //随机生成10以内的数,后面sleep里面要是毫秒,所以乘以1000
try {
sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 睡眠时间: "+i/1000);
}
}
|
package com.java.threadExercise;
import java.util.Random;
public class test3 {
/**
* 将所有线程修改成守护线程,并验证一旦main函数退出,程序立刻终止。
*/
public static void main(String[] args) {
Thread2 t1=new Thread2("No.1");
Thread2 t2=new Thread2("No.2");
Thread2 t3=new Thread2("No.3");
t1.setDaemon(true);
t2.setDaemon(true);
t3.setDaemon(true);
t1.start();
t2.start();
t3.start();
System.out.println("主线程结束。。。。");
}
}
class Thread2 extends Thread {
public Thread2(String string){
super(string);
}
public void run(){
super.run();
Random r1=new Random();
int i=r1.nextInt(11)*1000; //随机生成10以内的数,后面sleep里面要是毫秒,所以乘以1000
try {
sleep(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 睡眠时间: "+i/1000);
}
}
|
| test3.java | //test3.java |
|
public class test4 {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int num=in.nextInt();
Object obj=new Object();
int x=in.nextInt();
Thread3.getValue(num, x);
for(int i=0;i<num;++i){
new Thread3("第"+(i+1)+"个下载线程").start();
}
}
}
class Thread3 extends Thread{
public static int Num;
public static int X;
static Object obj=new Object();
public Thread3(String string){
super(string);
}
public static void getValue(int num,int x){
Num=num;
X=x;
}
public void run() {
super.run();
while(X>=0){
synchronized(obj){
//注意 ,这里要Obj必须是同一个对象才能实现加锁,不然会出现多把锁,失去意义;所以如果有多个线程对象,obj要声明成静态的
if(X<=0){
System.out.println("下载完成");
System.exit(0);
}
System.out.println(this.getName()+" :剩余"+X+"M未下载");
X--;
}
}
}
}
|
public class test4 {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int num=in.nextInt();
Object obj=new Object();
int x=in.nextInt();
Thread3.getValue(num, x);
Thread3 t3=new Thread3();
for(int i=0;i<num;++i){
new Thread(t3,"第"+(i+1)+"个下载线程").start(); //用同一个对象初始化线程,可以共用数据,下面run方法就可以不用把obj定义成static,因为所有线程都共用数据
}
}
}
class Thread3 implements Runnable{
public static int Num;
public static int X;
Object obj=new Object(); //不用定义成静态的
public static void getValue(int num,int x){
Num=num;
X=x;
}
public void run() {
while(X>=0){
synchronized(obj){
//this也可以,因为是一个对象初始化的线程
if(X<=0){
System.out.println("下载完成");
System.exit(0);
}
System.out.println(Thread.currentThread().getName()+" :剩余"+X+"M未下载");
X--;
}
}
}
}
|
Java——多线程小例子的更多相关文章
- Java多线程小例子(三个窗口卖火车票)
class Ticket implements Runnable{ private int TicketNum = 100; //100张火车票 private boolean flag = true ...
- java多线程小题一瞥
有如下线程类定义: public class MyThread extends Thread { private static int num = 0; public MyThread() { num ...
- java 多线程简单例子
实现线程的方式是一,继承Thread类,重写父类的run()方法 二,实现接口Runnable中的run()方法. 下面是简单的例子 例子1:银行存取钱问题 package com.direct.de ...
- 【多线程】java多线程 测试例子 详解wait() sleep() notify() start() join()方法 等
java实现多线程,有两种方法: 1>实现多线程,继承Thread,资源不能共享 2>实现多线程 实现Runnable接口,可以实现资源共享 *wait()方法 在哪个线程中调用 则当前 ...
- Java多线程小总结
多线程 线程与进程 线程:具有完成特定任务的一条执行路径,是CPU执行的最小单位 进程:正在执行的程序 重点:CPU在某个时间刻度上只能够执行一条原子性语句 字节最小是bit位 原子性语句:不能够再次 ...
- java反射小例子
package com.txwsqk.reflect; public class Car { private String brand; private String color; private i ...
- JSP调用JAVA方法小例子
用JAVA编写的函数 package doc; //定义一个包 public class Dy { //定义一个类 public static int Sub(int x,int y){ //定义函数 ...
- java算法小例子
作为一个程序员,有时候我觉得自己都不适合,因为自己数学不好,算法不好,脑子不够灵活.而对于算法,感觉就像是数学题,总觉得很难.以前上学,在班里总有几个什么都不好,但唯独数学很厉害,真气人!面对难题时, ...
- LigerUI java SSH小例子
1.新建web project 2.ssh框架 加入到项目中去(这里不介绍,网上搜索) 3.struts2配置 http://www.cnblogs.com/istianyu/archive/2013 ...
随机推荐
- POJ 1222 EXTENDED LIGHTS OUT(高斯消元)题解
题意:5*6的格子,你翻一个地方,那么这个地方和上下左右的格子都会翻面,要求把所有为1的格子翻成0,输出一个5*6的矩阵,把要翻的赋值1,不翻的0,每个格子只翻1次 思路:poj 1222 高斯消元详 ...
- mysql-5.7.20-winx64.zip Zip版、解压版MySQL安装
1. zip下载地址: https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.20-winx64.zip 2.官方文档位置: http:// ...
- 使用CCleaner卸载chrome
Google Chrome Update Patches Zero-Day Actively Exploited in the Wild 如果有同事使用google Chrome浏览器的话,请检查版本 ...
- 【附8】zipkin
一.zipkin作用 全链路追踪工具(查看依赖关系) 查看每个接口.每个service的执行速度(定位问题发生点或者寻找性能瓶颈) 二.zipkin工作原理 创造一些追踪标识符(tracingId,s ...
- K条最短路径算法(KSP, k-shortest pathes):Yen's Algorithm
参考: K最短路径算法之Yen's Algorithm Yen's algorithm 基于网络流量的SDN最短路径转发应用 K条最短路径算法:Yen's Algorithm 算法背景 K 最短路径问 ...
- 04_Flume多节点load_balance实践
1.负载均衡场景 1)初始:上游Agent通过round_robin selector, 将event轮流发送给下游Collecotor1, Collector2 2)故障: 关闭Collector1 ...
- idea oracle反向工程生成实体类
1. 选择View-Tool Window- Database 2. 配置数据库信息 提示:配置完成后可以通过idea进行sql查询等操作 3.在项目中创建hbernate.cfg.xml文件, 在r ...
- jquery扩展的两个方法与区别 $.extend $.fn.extend
jQuery.extend:Query本身的扩展方法 jQuery.fn.extent(Object) jquery 所选对象扩展方法 jQuery.extend 我们先把jQuery看成了一个类,这 ...
- django查询操作
查询操作是Django的ORM框架中最重要的内容之一.我们建立模型.保存数据为的就是在需要的时候可以查询得到数据.Django自动为所有的模型提供了一套完善.方便.高效的API,一些重要的,我们要背下 ...
- Codeforces 916B - Jamie and Binary Sequence (changed after round)
思路: 先取出二进制的每一位,判断总个数是不是小于等于k,如果大于k则不能构成. 通过观察可以发现,每一位的一个可以转换成下一位的两个,因为要使最大位尽可能小,所以如果最大位的所有的个数都可以转换成下 ...