java && C# 线程
1、多个线程用到同一个资源的话,必须lock
2、为了解决,在竞争的情况下,优先分配资源给A。就是A和B线程都同时在同一时刻需要资源x,然后的话也不清楚系统是具体怎样调度的。或者说怎样调度,都有可能出现上面的问题。解决方法是:在分配资源的时候再增加一个请求,用来排队。以前的请求是,如果这个时候申请然后这个时候也没人在用,就给它。现在的是如果B需要x,先要查看A是否需要。感觉有点像增加代码,然后使得线程判断次数增加,多次调度。所以感觉没有根本解决问题。
也不是说没解决,但是感觉解决了99.9%。hack,对于同一时刻到来的,还是随机化先进性读,或者先进性写了。T__T
怎么说呢,就是读者一来,先申请需要资源,而不是判定是否能拿资源,然后能拿就给它。我们需要的是先申请,然后就相当于锁定了资源x了,后来的写者再需要,需要检查申请队列中是否有读者,有就不行。
3、合法后立马addSignal,不然会出现多个写者同时操作的问题。
4、get, set方法是有用的,对于多线程,还可以维护资源不被多个线程修改,Lock
所以我的感觉是:如果是这样的:
写者先判定while (getNeedReader() > 0) { },判断失败的。
然后读者addReader(1);
然后写者while (getSignal() != 0) { } 也是失败的。
这样的话,结果还是给了写者。
很多人告诉我直接设置线程优先级,但是这样是不对的。因为线程的优先级只是说分配的时间片比较多,不保证上面的情况不能发生。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1 {
public partial class Form1 : Form {
static int signal = ;//0:empty 1:read 2:write
static int numberReader = , numberWriter = ;
private static object obj = new object();
private static object si = new object();
private static object reader = new object();
const int dis = ;
static Stopwatch timer1;
static int needReader = ;
class temp {
public string[] str;
int getSignal() {
lock (si) {
return signal;
}
}
int getNumber() {
if ( == getSignal()) return ;
else if ( == getSignal()) return numberReader;
else return numberWriter;
}
void addSignal(int id) {
lock (si) {
if (id == ) {
signal = ;
numberReader++;
} else {
signal = ;
numberWriter++;
}
}
}
void cutSignal(int id) {
lock (si) {
if (id == ) {
numberReader--;
if (numberReader == ) signal = ;
} else {
numberWriter--;
if (numberWriter == ) signal = ;
}
}
} void addStringRichText(String str) {
lock (obj) {
Form1.richTextBox1.Text += str;
Form1.richTextBox1.Text += '\n';
Form1.richTextBox1.Focus();
Form1.richTextBox1.Select(Form1.richTextBox1.Text.Length, );
Form1.richTextBox1.ScrollToCaret(); }
} void show(String[] str, int id) {
Console.Write(id + "+++ ");
for (int i = ; i < str.Length; ++i) {
Console.Write(str[i] + " ");
}
Console.WriteLine("\n");
} void addReader(int op) {
lock (reader) {
needReader += op;
}
} int getNeedReader() {
lock (reader) {
return needReader;
}
} void semWait(int id) {
if (id == ) {
addReader(); // 首先需要申请需要资源,直接资源锁定
if (getSignal() != ) {
addSignal(id);
return;
}
while (getSignal() == ) { } // 合法后立马addSignal
addSignal();
} else {
while (getNeedReader() > ) { }
while (getSignal() != ) { } //这句后面肯定要是addSignal,立马的
addSignal();
}
} void semSignal(int id) {
if (id == ) {
cutSignal();
addReader(-);
} else {
cutSignal();
}
} public void Reader() {
addStringRichText("读者:" + str[] + " 线程创建");
Thread.Sleep(int.Parse(str[]) * );
addStringRichText("读者:" + str[] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 请求读操作"); /*进行读操作*/
semWait();
addStringRichText("读者:" + str[] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 开始读操作");
Thread.Sleep(int.Parse(str[]) * );
addStringRichText("读者:" + str[] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 结束读操作");
semSignal();
/*读操作进行完毕*/ }
private static object w = new object();
public void Writer() {
addStringRichText("写者:" + str[] + " 线程创建");
Thread.Sleep(int.Parse(str[]) * );
addStringRichText("写者:" + str[] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 请求写操作"); semWait();
/*进行读操作*/ addStringRichText("写者:" + str[] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 开始写操作");
Thread.Sleep(int.Parse(str[]) * );
addStringRichText("写者:" + str[] + " 在时间:" + (int)timer1.Elapsed.TotalSeconds + " 结束写操作");
semSignal();
/*读操作进行完毕*/ } }
public Form1() {
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
OpenFileDialog op = new OpenFileDialog();
op.ShowDialog();
op.Filter = "All files(*.*)|*.*";
StreamReader reader = null; try {
string fileName = op.FileName;
if (fileName == "") {
return;
}
richTextBox1.Clear();
reader = new StreamReader(fileName, System.Text.Encoding.Default);
string str = reader.ReadLine();
List<Thread> list = new List<Thread>();
while (str != null) {
string[] res = str.Split(' ');
temp zhu = new temp();
zhu.str = res;
if (str.Contains("R") || str.Contains("r")) {
Thread rThread = new Thread(zhu.Reader);
//rThread.Priority = ThreadPriority.AboveNormal;
rThread.Priority = ThreadPriority.AboveNormal;
list.Add(rThread); } else if (str.Contains("W") || str.Contains("w")) {
Thread wThread = new Thread(zhu.Writer);
//wThread.Priority = ThreadPriority.BelowNormal;
list.Add(wThread);
} else {
MessageBox.Show("输入数据有错误!!!【每行数据后面不能有空格】,【文件结束不能有空行】");
return;
}
//MessageBox.Show(str);
str = reader.ReadLine();
}
timer1 = new Stopwatch();//计时器类
timer1.Start();
foreach (Thread i in list) {
i.Start();
}
} catch (Exception error) {
MessageBox.Show("错误信息是:" + error.Message, "警告", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally {
if (reader != null) {
reader.Close();
}
}
const string MutexName = "Multithreading";
var m = new Mutex(false, MutexName); }
private void richTextBox1_TextChanged(object sender, EventArgs e) {
}
private void Form1_Load(object sender, EventArgs e) {
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; //允许其他线程修改
}
}
}
所以,我感觉线程不是用于这样的东西的,这样的话结果不确定(或者是我太渣渣了)
线程应该是用在那些,计算方面,new一个线程来辅助计算
这个数据,就会显示是写者优先了,尽管我设置了优先级是读者AboveNormal
对了看到java里写,Main线程的优先级是Noraml的。
W
W
W
W
W
W
W
R
java说,
synchronized可以修饰一个同步一个方法,public synchronized void fun();
同步:就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。
java高级篇P326
一个同步方法在执行之前需要加锁,锁是一种实现资源排他使用的机制。对于实例方法,要给调用该方法的对象加锁。对于静态方法,要给这个类加锁。
但是我不需要对整个类加锁啊,我对静态方法加锁也可以得,???不懂
class myThread implements Runnable {
public String s; public void run() {
System.out.println(s);
} static synchronized void fun() { }
}
java的内部类如果需要new一个实体出来,
用name s = new name(); 是不行的。会"is not an enclosing class"
需要Main s = new Main(); 一个实例
然后Main.name bb = s.new name();
有一个问题就是,用lock的话,怎么解决只有一个return的语句呢???
因为lock.lock()之后,还需要lock.unlock()
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Main {
static bank bk = new bank();
public static void main(String[] args) {
ExecutorService ex = Executors.newCachedThreadPool();
ex.execute(new cutMoney());
ex.execute(new addMoney());
ex.shutdown();
}
static class addMoney implements Runnable {
@Override
public void run() {
while (true) {
int val = (int)(Math.random() * ) + ;
bk.add(val);
try {
Thread.sleep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
static class cutMoney implements Runnable {
@Override
public void run() {
while (true) {
int val = (int)(Math.random() * ) + ;
try {
while (!bk.cut(val)) {}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} static class bank {
private Lock lock = new ReentrantLock();
private Condition signal = lock.newCondition();
private int money = ;
bank() {}
// synchronized int getMoney() { // 只能这样嘛?用lock感觉不行啊
// return money;
// }
int getMoney() { // 只能这样嘛?用lock感觉不行啊
lock.lock();
try {
return money;
} finally {
lock.unlock();
}
}
String getNowTime() {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ");//设置日期格式
return (df.format(new Date()));// new Date()为获取当前系统时间
}
boolean cut(int val) throws InterruptedException {
lock.lock();
try {
while (money < val) {
System.out.println(getNowTime() + " 不够 " + val + " " + " 现在有 " + money);
signal.await(); //等待,不需要一直判判判
}
money -= val;
System.out.println(getNowTime() + " 扣除" + val + "钱");
} catch (InterruptedException e) { } finally {
lock.unlock();
}
return true; }
void add(int val) {
lock.lock();
try {
money += val;
System.out.println(getNowTime() + " 转入" + val + "钱");
signal.signalAll(); // 唤醒
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
减钱加钱
我的方法是:
1、用synchronized
2、try的finally语句是必须进行的
java && C# 线程的更多相关文章
- java之线程
java之线程 一:线程: 线程是什么呢?线程,有时被称为轻量级进程是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成.另外,线程是进程中的一个实体,是被系统 ...
- Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别
一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...
- Java的线程安全
线程安全 我们这里讨论的线程安全,就限定于多个线程之间存在共享数据访问这个前提,因为如果一段代码根本不会与其他线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它来说是完全没有区别 ...
- 深入理解Java之线程池
原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...
- java中线程分两种,守护线程和用户线程。
java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...
- java 多线程—— 线程让步
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- java 多线程—— 线程等待与唤醒
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- Java的线程模型
并发不一定要依赖多线程(如PHP中很常见的多进程并发),但是在Java里面谈论并发,大多数都与线程脱不开关系. 线程是比进程更轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和执行调度分开, ...
- Java多线程 - 线程状态
转自: http://www.cnblogs.com/lwbqqyumidi/p/3804883.html 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的 ...
- Java Thread线程控制
一.线程和进程 进程是处于运行中的程序,具有一定的独立能力,进程是系统进行资源分配和调度的一个独立单位. 进程特征: A.独立性:进程是系统中独立存在的实体,可以拥有自己独立的资源,每个进程都拥有自己 ...
随机推荐
- 小小c#算法题 - 8 - 归并排序 (Merging Sort)
“归并”的含义是将两个或两个以上的有序序列组合成一个新的有序序列.这个“归并”可以在O(n+m)的数量级上实现,但这同时也需要O(n+m)的空间复杂度.具体为:首先分配一个新的长度为n+m的空序列,然 ...
- java 字符流 字节流
java对文本文档进行操作(拷贝.显示)出现乱码一般来说,可以从两个方面入手. 1.文本文件本身的编码格式. 2.java代码中处理文本文件的编码格式. 这里要注意的一点是,我们可以看出copyFil ...
- 批量更改某一目录之下所有文件名 Ver2
前一篇<批量更改某一目录之下所有文件名>只是批量修改所有子目录下的文件名.Insus.NET重构了它.能让它修改所有子目录名和子目录下的文件名.就是分别迭代,目录迭代目录,文件迭代文件. ...
- Join方法把阵列转为字符串
string有一个方法,就是Join,可以把阵列转换为字符串: 下面是Join方法重载,可以指定那个元素开始,连续取几个元素: 可以传入一个IEnumerable<T>参数:
- RPM软件包管理以及使用方法
Red Hat Package Manager(简称RPM)工具包由于其使用简单操作方便,可以实现软件的查询.安装.卸载.升级和验证等功能,为Linux使用者节省大量的时间,所以被广泛的用于Linux ...
- cenos php执行pdf2swf 配置环境
1.第一步:安装xpdf语言包 1.mkdir –p /usr/share/xpdf 2.cd /usr/share/xpdf/ 3.下载中文支持及字体库wget ftp://ftp.foolabs. ...
- github 的使用步骤
1. github是一个git项目托管网站 注册地址:https://github.com/signup/free 2. 安装git程序,执行下面操作 $ cd ~/.ssh //检查计算机ssh密钥 ...
- SQL基础(一)
经过这段时间对SQL的基础学习,下面对自己的学习做个总结或者也可以说是个回顾吧! 我练习的是在oracle数据库平台上,并且安装了PLSQL Developer工具.下面是我从小白开始一路学习的回顾: ...
- CF796C Bank Hacking 思维
Although Inzane successfully found his beloved bone, Zane, his owner, has yet to return. To search f ...
- MySQL数据查询结果导出生成文件
select url from news where url like "%美女%" into outfile "/导出的文件路径" : 在这里有个坑,对于 ...